skiv 0.0.2 → 0.0.5

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 (68) hide show
  1. package/README.md +6 -3
  2. package/bin/skiv.ts +3 -0
  3. package/package.json +9 -4
  4. package/skeleton/config.yaml +2 -2
  5. package/skeleton/roles/corder/CLAUDE.md +26 -44
  6. package/skeleton/roles/corder/custom.ts +43 -26
  7. package/skeleton/roles/pm/.claude/settings.local.json +13 -0
  8. package/skeleton/roles/pm/CLAUDE.md +56 -0
  9. package/skeleton/roles/pm/custom.ts +75 -0
  10. package/skeleton/roles/reviewer/CLAUDE.md +31 -31
  11. package/skeleton/roles/reviewer/custom.ts +49 -21
  12. package/skeleton/roles/se/CLAUDE.md +11 -5
  13. package/skeleton/spec.md +0 -0
  14. package/skeleton/worker.ts +29 -0
  15. package/bin/________________________skiv.ts +0 -3
  16. package/bin/skiv.js +0 -3
  17. package/dist/cjs/IssueService.js +0 -236
  18. package/dist/cjs/Logger.js +0 -39
  19. package/dist/cjs/Member.js +0 -83
  20. package/dist/cjs/cli.js +0 -94
  21. package/dist/cjs/commands/Command.js +0 -66
  22. package/dist/cjs/commands/InitCommand.js +0 -27
  23. package/dist/cjs/commands/IssueCommand.js +0 -39
  24. package/dist/cjs/commands/RunCommand.js +0 -57
  25. package/dist/cjs/commands/StartCommand.js +0 -69
  26. package/dist/cjs/db/index.js +0 -27
  27. package/dist/cjs/db/migrations.js +0 -36
  28. package/dist/cjs/db/schema.js +0 -25
  29. package/dist/cjs/utils.js +0 -32
  30. package/dist/esm/IssueService.d.ts +0 -65
  31. package/dist/esm/IssueService.d.ts.map +0 -1
  32. package/dist/esm/IssueService.js +0 -232
  33. package/dist/esm/Logger.d.ts +0 -21
  34. package/dist/esm/Logger.d.ts.map +0 -1
  35. package/dist/esm/Logger.js +0 -36
  36. package/dist/esm/Member.d.ts +0 -21
  37. package/dist/esm/Member.d.ts.map +0 -1
  38. package/dist/esm/Member.js +0 -77
  39. package/dist/esm/cli.d.ts +0 -2
  40. package/dist/esm/cli.d.ts.map +0 -1
  41. package/dist/esm/cli.js +0 -89
  42. package/dist/esm/commands/Command.d.ts +0 -19
  43. package/dist/esm/commands/Command.d.ts.map +0 -1
  44. package/dist/esm/commands/Command.js +0 -30
  45. package/dist/esm/commands/InitCommand.d.ts +0 -5
  46. package/dist/esm/commands/InitCommand.d.ts.map +0 -1
  47. package/dist/esm/commands/InitCommand.js +0 -21
  48. package/dist/esm/commands/IssueCommand.d.ts +0 -10
  49. package/dist/esm/commands/IssueCommand.d.ts.map +0 -1
  50. package/dist/esm/commands/IssueCommand.js +0 -33
  51. package/dist/esm/commands/RunCommand.d.ts +0 -5
  52. package/dist/esm/commands/RunCommand.d.ts.map +0 -1
  53. package/dist/esm/commands/RunCommand.js +0 -18
  54. package/dist/esm/commands/StartCommand.d.ts +0 -28
  55. package/dist/esm/commands/StartCommand.d.ts.map +0 -1
  56. package/dist/esm/commands/StartCommand.js +0 -63
  57. package/dist/esm/db/index.d.ts +0 -6
  58. package/dist/esm/db/index.d.ts.map +0 -1
  59. package/dist/esm/db/index.js +0 -19
  60. package/dist/esm/db/migrations.d.ts +0 -3
  61. package/dist/esm/db/migrations.d.ts.map +0 -1
  62. package/dist/esm/db/migrations.js +0 -33
  63. package/dist/esm/db/schema.d.ts +0 -46
  64. package/dist/esm/db/schema.d.ts.map +0 -1
  65. package/dist/esm/db/schema.js +0 -20
  66. package/dist/esm/utils.d.ts +0 -7
  67. package/dist/esm/utils.d.ts.map +0 -1
  68. package/dist/esm/utils.js +0 -25
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Installation
4
4
 
5
5
  ```shell
6
- npm i -g skiv
6
+ $ npm i -g skiv
7
7
  ```
8
8
 
9
9
  ## Usage
@@ -13,15 +13,18 @@ npm i -g skiv
13
13
  cd to your project directory
14
14
 
15
15
  ```shell
16
- npx skiv init
16
+ $ npx skiv init
17
17
  ```
18
18
 
19
19
  generate `.skiv` directory
20
20
 
21
21
  edit `.skiv/config.yaml` and `.skiv/roles/*`
22
22
 
23
+ add `.skiv` to your gitignore
24
+
23
25
  ### Start
24
26
 
25
27
  ```shell
26
- npx skiv start
28
+ $ tmux
29
+ $ npx skiv start
27
30
  ```
package/bin/skiv.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ import "../skiv/cli"
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "skiv",
3
- "version": "0.0.2",
3
+ "version": "0.0.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "description": "claude code orchestration tool",
8
8
  "license": "MIT",
9
9
  "author": "",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/masashimachida/skiv.git"
13
+ },
10
14
  "type": "commonjs",
11
15
  "main": "dist/esm/index.js",
12
16
  "scripts": {
@@ -22,14 +26,13 @@
22
26
  "skeleton"
23
27
  ],
24
28
  "bin": {
25
- "skiv": "bin/skiv.js"
29
+ "skiv": "bin/skiv.ts"
26
30
  },
27
31
  "devDependencies": {
28
32
  "@types/better-sqlite3": "^7.6.13",
29
33
  "@types/fs-extra": "^11.0.4",
30
34
  "@types/js-yaml": "^4.0.9",
31
35
  "@types/node": "^25.2.0",
32
- "tsx": "^4.21.0",
33
36
  "typescript": "^5.9.3"
34
37
  },
35
38
  "dependencies": {
@@ -37,6 +40,8 @@
37
40
  "commander": "^14.0.3",
38
41
  "fs-extra": "^11.3.3",
39
42
  "js-yaml": "^4.1.1",
40
- "kysely": "^0.28.11"
43
+ "kysely": "^0.28.11",
44
+ "simple-git": "^3.30.0",
45
+ "tsx": "^4.21.0"
41
46
  }
42
47
  }
@@ -1,6 +1,6 @@
1
1
  model: sonnet
2
2
  members:
3
- - name: Corder001
3
+ - name: CORDER
4
4
  role: corder
5
- - name: Reviewer001
5
+ - name: REVIEWER
6
6
  role: reviewer
@@ -9,58 +9,40 @@
9
9
 
10
10
  ### 2. 前提条件
11
11
  - ブランチ名: `issues/issue-<issue.id>`
12
- - 作業パス: `repo/issues/issue-<issue.id>`
12
+ - 作業パス: `worktree`
13
13
 
14
- ### 3. 作業環境の準備
15
- Issueが存在する場合、以下の手順で作業ブランチを作成します。
16
- - Git Worktreeを作成: `git worktree add <作業パス> -b <ブランチ名> || git worktree add <作業パス> <ブランチ名>`
17
- - **作業ディレクトリへ移動: `cd <作業パス>`**
18
-
19
- ### 4. 実装
14
+ ### 3. 実装
20
15
  Issueのタイトルや仕様を確認し、実装を行います。
21
16
  - **実装前に既存の関連コードを読み、プロジェクトのコーディングスタイルを確認してください。**
17
+ - ファイルの更新は作業パス以外行わないこと。
22
18
  - 変更は最小限に留めること。
23
19
  - 関連のないコードをリファクタリングしないこと。
24
20
 
25
- ### 5. コミット
26
- 変更完了後、以下の形式でコミットします。
27
- - メッセージ: `<type>: issue #<issue.id> <issue.title>`
28
- - <type>は新機能なら `feat`, 修正なら `fix` を使用。
29
-
30
- ### 6. worktree削除
31
- - コマンド: `git worktree remove <ブランチ名>`
32
-
33
- ### 7. レビュー準備
34
- 最後にIssueを更新して完了報告をします。
35
- `npx skiv issue update_status <issue.id> ready_for_review`
36
-
37
-
38
- ## 利用可能なツール
39
-
40
- Issue Tool:
41
- npx skiv issue
42
-
43
- Git:
44
- git
45
-
46
- ### 使用可能なコマンド
47
-
48
- Issue Tool:
49
- - ready_for_review
50
-
51
- Git:
52
- - worktree
53
- - add
54
- - commit
55
- - diff
21
+ ### コミット
22
+ コミットなどの作業はやらないこと。
23
+
24
+ ## アウトプット形式
25
+ からなず以下のjson形式で出力してください。
26
+ 出力をこのままパースするので、json以外の出力をしないでください。
27
+ 「```json」などの修飾もしないでください。
28
+ 絶対に以下のJSON以外を出力しないでください。
29
+
30
+ 正常時:
31
+ {
32
+ "result": "FINISH",
33
+ "branch": "<ブランチ名>",
34
+ "issue_title": "<issue名>"
35
+ }
36
+
37
+ 異常時:
38
+ {
39
+ "result": "ERROR",
40
+ "branch": "<ブランチ名>",
41
+ "issue_title": "<issue名>",
42
+ "reason": "<完了しなかった理由>"
43
+ }
56
44
 
57
45
  ## 禁止事項
58
46
  - 新しいIssueの作成
59
47
  - 他タスクのレビュー
60
48
  - 割り当てられたタスク範囲外のファイル編集
61
-
62
- ## 行動ルール
63
- 1. タスクを取得する
64
- 2. 実装する
65
- 3. コミットする
66
- 4. レビュー準備完了としてマークする
@@ -1,39 +1,21 @@
1
- import {Issue} from "../../../../skiv/src/db/schema";
2
- import Member from "../../../src/Member";
1
+ import {Issue} from "skiv/skiv/db/schema"
2
+ import AbstractWorker from "../../worker"
3
3
 
4
- export default class CustomMember extends Member {
4
+ export default class Custom extends AbstractWorker {
5
5
 
6
6
  public async before(): Promise<boolean> {
7
- const assignedIssue = await this.issueService.getAssignedIssue(this.NAME, 'open')
7
+ this.logger.debug('before()')
8
+ const assignedIssue = await this.issueService.getNextIssue('open', 'in_progress', this.NAME)
8
9
  if (assignedIssue) {
9
-
10
- console.log(`[NEW ISSUE]
11
- Title: ${assignedIssue.title}
12
- Description: ${assignedIssue.description}
13
- `)
14
-
15
- this.createPrompt(assignedIssue)
16
- return true
17
- }
18
-
19
- const assign = await this.issueService.assignNextIssue(this.NAME)
20
- if (assign) {
21
-
22
- console.log(`[NEW ISSUE]
23
- Title: ${assign.title}
24
- Description: ${assign.description}
25
- `)
26
-
27
- this.createPrompt(assign)
10
+ this.logger.info(`found issue: #${assignedIssue.id} ${assignedIssue.title}`)
11
+ await this.setup(assignedIssue)
28
12
  return true
29
13
  }
30
14
 
31
- console.log('no issue')
32
-
33
15
  return false
34
16
  }
35
17
 
36
- private createPrompt(issue: Issue) {
18
+ protected createPrompt(issue: Issue): void {
37
19
 
38
20
  const comments = issue.comments?.map(comment => {
39
21
  return `- id: ${comment.id}
@@ -59,4 +41,39 @@ ${comments}
59
41
 
60
42
  このあとはCLAUDE.mdに沿って処理をしてください。`
61
43
  }
44
+
45
+ public async after(response: string): Promise<void> {
46
+ this.logger.debug('after()')
47
+
48
+ if (!this.ISSUE_ID) {
49
+ throw new Error('ISSUE_ID is not set')
50
+ }
51
+ const res = this.parseResponse<{
52
+ result: "FINISH" | "ERROR",
53
+ branch: string,
54
+ issue_title: string,
55
+ reason?: string
56
+ }>(response)
57
+
58
+ if (res.result === "FINISH") {
59
+
60
+ try {
61
+ await this.git
62
+ .add('.')
63
+ .commit(`feature: issue #${this.ISSUE_ID} ${res.issue_title}`)
64
+ await this.issueService.updateStatus(this.ISSUE_ID, 'ready_for_review')
65
+ } catch (e) {
66
+ this.logger.error(e as string)
67
+ process.exit(1)
68
+ } finally {
69
+ await this.cleanupWorktree()
70
+ }
71
+
72
+ } else {
73
+ this.logger.error(res)
74
+ await this.issueService.updateStatus(this.ISSUE_ID, 'error')
75
+ await this.cleanupWorktree()
76
+ process.exit(1)
77
+ }
78
+ }
62
79
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx skiv issue *)",
5
+ "Bash(git *)"
6
+ ],
7
+ "deny": [
8
+ "Bash(curl:*)",
9
+ "Read(./.env)",
10
+ "Read(./.env.*)"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,56 @@
1
+ # ROLE: Project Manager
2
+
3
+ あなたは指定されたブランチをmainブランチにマージをします。
4
+ 適宜、仕様書(spec.md)を参照します。
5
+
6
+ ## ワークフロー
7
+
8
+ ### 1. マージする Issue の取得
9
+ プロンプトで渡された Issue を参照してください。
10
+
11
+ ### 2. 前提条件
12
+ - ブランチ名: `issues/issue-<issue.id>`
13
+
14
+ ### 3. マージ
15
+ 該当のブランチをmainへマージします。
16
+ コンフリクトした場合は適宜修正をしてコンフリクトを解消してください。
17
+ 修正の判断がつかない場合は無理に解消しようとしないでください。
18
+
19
+ ## アウトプット形式
20
+ からなず以下のjson形式で出力してください。
21
+ 出力をこのままパースするので、json以外の出力をしないでください。
22
+ 「```json」などの修飾もしないでください。
23
+ 絶対に以下のJSON以外を出力しないでください。
24
+
25
+ マージOK時:
26
+ {
27
+ "result": "MERGED",
28
+ "branch": "<ブランチ名>",
29
+ "issue_title": "<issue名>",
30
+ "reason": "<何かコメントがあれば>"
31
+ }
32
+
33
+ コンフリクトが解消できない時:
34
+ {
35
+ "result": "CONFLICT",
36
+ "branch": "<ブランチ名>",
37
+ "issue_title": "<issue名>",
38
+ "reason": "<コンフリクトが解消できなかった理由>"
39
+ }
40
+
41
+ 異常時:
42
+ {
43
+ "result": "ERROR",
44
+ "branch": "<ブランチ名>",
45
+ "issue_title": "<issue名>",
46
+ "reason": "<完了しなかった理由>"
47
+ }
48
+
49
+ ### 実施可能なこと
50
+ - 差分の確認
51
+ - コンフリクトの解消
52
+ - gitの操作
53
+
54
+ ## 禁止事項
55
+ - Issueの作成
56
+ - Issueのアサイン
@@ -0,0 +1,75 @@
1
+ import {Issue} from "skiv/skiv/db/schema"
2
+ import AbstractWorker from "../../worker"
3
+
4
+ export default class CustomMember extends AbstractWorker {
5
+
6
+ public async before(): Promise<boolean> {
7
+ this.logger.debug('before()')
8
+ const issue = await this.issueService.getNextIssue('request_for_merge', 'in_merge_process', this.NAME)
9
+ if (issue) {
10
+ this.logger.info(`found issue: #${issue.id} ${issue.title}`)
11
+ await this.setup(issue)
12
+ return true
13
+ }
14
+
15
+ return false
16
+ }
17
+
18
+ protected createPrompt(issue: Issue) {
19
+
20
+ const comments = issue.comments?.map(comment => {
21
+ return `- id: ${comment.id}
22
+ by: ${comment.by}
23
+ message: ${comment.message}
24
+ `
25
+ }).join("\n") || ''
26
+
27
+ this.PROMPT = `あなたの名前は \`${this.NAME}\` です。
28
+ あなたがレビューするタスクは以下の通りです。
29
+
30
+ id:
31
+ ${issue.id}
32
+
33
+ タスク名:
34
+ ${issue.title}
35
+
36
+ 概要:
37
+ ${issue.description}
38
+
39
+ コメント:
40
+ ${comments}
41
+
42
+ このあとはCLAUDE.mdに沿って処理をしてください。`
43
+ }
44
+
45
+ public async after(response: string): Promise<void> {
46
+ this.logger.debug('after()')
47
+
48
+ if (!this.ISSUE_ID) {
49
+ throw new Error('ISSUE_ID is not set')
50
+ }
51
+
52
+ const res = this.parseResponse<{
53
+ result: "MERGED" | "ERROR",
54
+ branch: string,
55
+ issue_title: string,
56
+ reason?: string
57
+ }>(response)
58
+
59
+ if (res.result === "MERGED") {
60
+
61
+ await this.issueService.updateStatus(this.ISSUE_ID, 'done')
62
+ if (res.reason) {
63
+ await this.issueService.comment(this.ISSUE_ID, this.NAME, res.reason)
64
+ }
65
+ } else {
66
+ this.logger.error(res)
67
+ await this.issueService.updateStatus(this.ISSUE_ID, 'error')
68
+ await this.issueService.comment(this.ISSUE_ID, this.NAME, res.reason || "(no reason)")
69
+ await this.cleanupWorktree()
70
+ process.exit(1)
71
+ }
72
+
73
+ await this.cleanupWorktree()
74
+ }
75
+ }
@@ -9,50 +9,50 @@
9
9
 
10
10
  ### 2. 前提条件
11
11
  - ブランチ名: `issues/issue-<issue.id>`
12
- - 作業パス: `repo/issues/issue-<issue.id>`
12
+ - 作業パス: `worktree`
13
13
 
14
- ### 3. 作業環境の準備
15
- Issue が存在する場合、以下の手順で作業ブランチを作成します。
16
- - Git Worktree を作成: `git worktree add <作業パス> -b <ブランチ名> || git worktree add <作業パス> <ブランチ名>`
17
- - **作業ディレクトリへ移動: `cd <作業パス>`**
18
-
19
- ### 4. レビュー
14
+ ### 3. レビュー
20
15
  Issue のタイトルや仕様を確認し、以下の観点から実装が適切に行われているか確認します。
21
16
  - コーディングスタイルに沿っているか
22
17
  - テストは充実しているか
23
18
  - 変更は最小限に留まっているか
24
19
  - Issue に関連のない変更をしていないか
25
20
 
26
- ### 5. worktree削除
27
- ブランチを削除します
28
- - コマンド: `git worktree remove <ブランチ名>`
29
-
30
- ### 6. マージリクエスト / 却下
31
- コードに問題がなければ Issue をマージリクエストの状態にします。
32
- - コマンド: `npx skiv issue update_status <issue.id> request_for_merge`
33
-
34
- 問題があれば指摘事項をコメントして Issue を再び assign に戻します。
35
- - コマンド:
36
- - `npx skiv issue comment <issue.id> <YOUR_NAME> <message>`
37
- - `npx skiv issue assign <issue.id> <YOUR_NAME>`
38
-
39
- ## 利用可能なツール
40
-
41
- Issue Tool:
42
- npx skiv issue
43
-
44
- Git:
45
- git diff
21
+ ## アウトプット形式
22
+ からなず以下のjson形式で出力してください。
23
+ 出力をこのままパースするので、json以外の出力をしないでください。
24
+ 「```json」などの修飾もしないでください。
25
+ 絶対に以下のJSON以外を出力しないでください。
26
+
27
+ レビューOK時:
28
+ {
29
+ "result": "APPROVED",
30
+ "branch": "<ブランチ名>",
31
+ "issue_title": "<issue名>",
32
+ "reason": "<何かコメントがあれば>"
33
+ }
34
+
35
+ レビューNG時:
36
+ {
37
+ "result": "REJECT",
38
+ "branch": "<ブランチ名>",
39
+ "issue_title": "<issue名>",
40
+ "reason": "<却下の理由/修正点>"
41
+ }
42
+
43
+ 異常時:
44
+ {
45
+ "result": "ERROR",
46
+ "branch": "<ブランチ名>",
47
+ "issue_title": "<issue名>",
48
+ "reason": "<完了しなかった理由>"
49
+ }
46
50
 
47
51
  ### 実施可能なこと
48
52
  - 差分の確認
49
53
  - レビューコメントの追加
50
54
  - 完了としてマーク
51
55
 
52
- ### 例
53
- npx skiv issue comment 12 Reviewer "Refactor this function"
54
- npx skiv issue done 12
55
-
56
56
  ## 禁止事項
57
57
  - 実装コードの作成
58
58
  - Issueの作成
@@ -1,31 +1,21 @@
1
- import {Issue} from "../../../../skiv/src/db/schema";
2
- import Member from "../../../src/Member";
1
+ import {Issue} from "skiv/skiv/db/schema"
2
+ import AbstractWorker from "../../worker"
3
3
 
4
- export default class CustomMember extends Member {
4
+ export default class CustomMember extends AbstractWorker {
5
5
 
6
6
  public async before(): Promise<boolean> {
7
- const readyForReviewIssue = await this.issueService.getReviewIssue()
8
-
9
- if (!readyForReviewIssue) {
10
- console.log('no issue for review')
11
- return false
7
+ this.logger.debug('before()')
8
+ const readyForReviewIssue = await this.issueService.getNextIssue('ready_for_review', 'reviewing', this.NAME)
9
+ if (readyForReviewIssue) {
10
+ this.logger.info(`found issue: #${readyForReviewIssue.id} ${readyForReviewIssue.title}`)
11
+ await this.setup(readyForReviewIssue)
12
+ return true
12
13
  }
13
14
 
14
- // if (readyForReviewIssue.status !== 'ready_for_review') {
15
- // console.log('issue is not ready for review')
16
- // return false
17
- // }
18
-
19
- console.log(`[NEW ISSUE]
20
- Title: ${readyForReviewIssue.title}
21
- Description: ${readyForReviewIssue.description}
22
- `)
23
-
24
- this.createPrompt(readyForReviewIssue)
25
- return true
15
+ return false
26
16
  }
27
17
 
28
- private createPrompt(issue: Issue) {
18
+ protected createPrompt(issue: Issue) {
29
19
 
30
20
  const comments = issue.comments?.map(comment => {
31
21
  return `- id: ${comment.id}
@@ -51,4 +41,42 @@ ${comments}
51
41
 
52
42
  このあとはCLAUDE.mdに沿って処理をしてください。`
53
43
  }
44
+
45
+ public async after(response: string): Promise<void> {
46
+ this.logger.debug('after()')
47
+
48
+ if (!this.ISSUE_ID) {
49
+ throw new Error('ISSUE_ID is not set')
50
+ }
51
+
52
+ const res = this.parseResponse<{
53
+ result: "APPROVED" | "REJECT" | "ERROR",
54
+ branch: string,
55
+ issue_title: string,
56
+ reason?: string
57
+ }>(response)
58
+
59
+ if (res.result === "APPROVED") {
60
+
61
+ await this.issueService.updateStatus(this.ISSUE_ID, 'request_for_merge')
62
+ if (res.reason) {
63
+ await this.issueService.comment(this.ISSUE_ID, this.NAME, res.reason)
64
+ }
65
+
66
+ } else if (res.result === "REJECT") {
67
+
68
+ await this.issueService.updateStatus(this.ISSUE_ID, 'open')
69
+ await this.issueService.updateAssignee(this.ISSUE_ID, null)
70
+ await this.issueService.comment(this.ISSUE_ID, this.NAME, res.reason || "(no reason)")
71
+
72
+ } else {
73
+ this.logger.error(res)
74
+ await this.issueService.updateStatus(this.ISSUE_ID, 'error')
75
+ await this.issueService.comment(this.ISSUE_ID, this.NAME, res.reason || "(no reason)")
76
+ await this.cleanupWorktree()
77
+ process.exit(1)
78
+ }
79
+
80
+ await this.cleanupWorktree()
81
+ }
54
82
  }
@@ -1,6 +1,7 @@
1
1
  # ROLE: SE (System Engineer Agent)
2
2
 
3
- あなたの責任範囲は計画立案とタスク分解のみです。
3
+ あなたの責任範囲は計画立案とタスク分解のみです
4
+ ただし仕様書(spec.md)の編集だけは行えます。
4
5
 
5
6
  ## 利用可能なツール
6
7
 
@@ -15,7 +16,7 @@ npx skiv issue
15
16
  ### 例
16
17
 
17
18
  Issueの作成:
18
- npx skiv issue create "Implement auth API" high design.md#auth
19
+ npx skiv issue create "fizzbuzz.tsの作成" high "1から順に数を数え上げ、3の倍数で「Fizz」、5の倍数で「Buzz」、15の倍数(3と5の公倍数)で「FizzBuzz」と表示する関数を作成する"
19
20
 
20
21
  優先度は次のいずれかである必要があります:
21
22
  - low
@@ -25,8 +26,7 @@ npx skiv issue create "Implement auth API" high design.md#auth
25
26
  他の値が必要な場合は、最も近いものを選択してください。
26
27
  新しい優先度レベルを作成してはいけません。
27
28
 
28
- 指示コメントの追加:
29
- npx skiv issue comment 12 SE "Use JWT auth"
29
+ 説明(作業指示)を必ず記述してください。
30
30
 
31
31
  ## 禁止事項
32
32
  - ソースコードの編集
@@ -36,6 +36,12 @@ npx skiv issue comment 12 SE "Use JWT auth"
36
36
 
37
37
  ## 行動ルール
38
38
  - 要件を小さなタスクに分解すること
39
- - ただし実装とテストは同一のタスクにすること
39
+ - タスクを分割する際は、以下の制約を厳守してください。
40
+ - 粒度:1つのエンドポイント、1つのUIパーツ、1つのロジック関数
41
+ - 禁止:『〜の構築』『〜の実装』といった大きな単位
42
+ - 推奨:『xxxをyyyに追加してzzzできるようにする』という具体的な記述
43
+ - 1つのタスクは、シニアエンジニアが 30分以内に実装・テスト完了できる規模 であること
44
+ - 実装とテストは同一のタスクにすること
40
45
  - 各タスクは単独で実装可能でなければならない
41
46
  - 常に仕様書の該当セクションを参照すること
47
+ - 必要に応じて仕様書を修正すること
File without changes
@@ -0,0 +1,29 @@
1
+ import {Issue} from "skiv/skiv/db/schema";
2
+ import Worker from "skiv/skiv/Worker";
3
+
4
+ export default abstract class AbstractWorker extends Worker {
5
+
6
+ protected ISSUE_ID: number | null = null
7
+
8
+ protected async setup(issue: Issue) {
9
+ this.ISSUE_ID = issue.id
10
+ await this.cleanupWorktree()
11
+ await this.setupWorktree(`issues/issue-${issue.id}`)
12
+ this.createPrompt(issue)
13
+ }
14
+
15
+ protected abstract createPrompt(issue: Issue): void
16
+
17
+ protected parseResponse<T>(response: string): T {
18
+ const matches = response.match(/\{[\s\S]*\}/)
19
+ const jsonStr = matches ? matches[0] : response
20
+
21
+ const parsed = JSON.parse(jsonStr) as T
22
+
23
+ this.logger.debug('----------------------')
24
+ this.logger.debug(parsed as unknown as object)
25
+ this.logger.debug('----------------------')
26
+
27
+ return parsed
28
+ }
29
+ }
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- import "../src/cli";
package/bin/skiv.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- require('../dist/cjs/cli.js')