bobbi-agent 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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/dist/auth.d.ts +65 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +152 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +245 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +29 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +72 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/daemon.d.ts +17 -0
  16. package/dist/daemon.d.ts.map +1 -0
  17. package/dist/daemon.js +76 -0
  18. package/dist/daemon.js.map +1 -0
  19. package/dist/file-generator.d.ts +6 -0
  20. package/dist/file-generator.d.ts.map +1 -0
  21. package/dist/file-generator.js +129 -0
  22. package/dist/file-generator.js.map +1 -0
  23. package/dist/git-manager.d.ts +37 -0
  24. package/dist/git-manager.d.ts.map +1 -0
  25. package/dist/git-manager.js +135 -0
  26. package/dist/git-manager.js.map +1 -0
  27. package/dist/index.d.ts +6 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +5 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/sync-engine.d.ts +14 -0
  32. package/dist/sync-engine.d.ts.map +1 -0
  33. package/dist/sync-engine.js +97 -0
  34. package/dist/sync-engine.js.map +1 -0
  35. package/dist/types.d.ts +62 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +2 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/websocket-client.d.ts +48 -0
  40. package/dist/websocket-client.d.ts.map +1 -0
  41. package/dist/websocket-client.js +33 -0
  42. package/dist/websocket-client.js.map +1 -0
  43. package/package.json +66 -0
  44. package/templates/post-checkout +28 -0
  45. package/templates/post-commit +27 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-engine.js","sourceRoot":"","sources":["../src/sync-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Sprint payload shape aligned with Sprint Planner (Sprint / dbSprintToSprint).
3
+ */
4
+ export interface Sprint {
5
+ id: string;
6
+ name: string;
7
+ goal: string;
8
+ status: "active" | "completed" | "planned";
9
+ progress: number;
10
+ totalTasks: number;
11
+ completedTasks: number;
12
+ estimatedHours: number;
13
+ createdAt: string;
14
+ userStories: string[];
15
+ acceptanceCriteria: string[];
16
+ tasks: {
17
+ frontend: string[];
18
+ backend: string[];
19
+ auth: string[];
20
+ };
21
+ completedTaskNames?: string[];
22
+ estimates: {
23
+ frontend: string;
24
+ backend: string;
25
+ qa: string;
26
+ total: string;
27
+ };
28
+ ai_draft_version_id?: string | null;
29
+ }
30
+ /**
31
+ * ./.bobbi/config.json
32
+ */
33
+ export interface BobbiConfig {
34
+ project_id: string;
35
+ api_url: string;
36
+ environment: string;
37
+ auto_start: boolean;
38
+ /** Encrypted or opaque; never store GitHub tokens */
39
+ refresh_token?: string;
40
+ access_token?: string;
41
+ access_token_expires_at?: number;
42
+ }
43
+ /**
44
+ * ./.bobbi/state.json
45
+ */
46
+ export interface BobbiState {
47
+ last_sync_time: string;
48
+ last_commit_hash: string;
49
+ active_branch: string;
50
+ sprint_version: string;
51
+ }
52
+ /**
53
+ * ./.bobbi/context.json — AI-optimized execution context
54
+ */
55
+ export interface BobbiContext {
56
+ sprint_goal: string;
57
+ current_task: string;
58
+ task_priority: number;
59
+ relevant_files: string[];
60
+ constraints: string[];
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import WebSocket from "ws";
2
+ import type { Sprint } from "./types.js";
3
+ export type WSMessageFromServer = {
4
+ type: "sprint_update";
5
+ sprint: Sprint | null;
6
+ } | {
7
+ type: "task_progress_ack";
8
+ task_id?: string;
9
+ commit_hash: string;
10
+ status: string;
11
+ } | {
12
+ type: "branch_ack";
13
+ branch: string;
14
+ } | {
15
+ type: "pong";
16
+ ts?: number;
17
+ } | {
18
+ type: "error";
19
+ code: string;
20
+ message: string;
21
+ } | {
22
+ type: "connected";
23
+ project_id?: string;
24
+ };
25
+ export type WSMessageFromClient = {
26
+ type: "subscribe";
27
+ project_id: string;
28
+ } | {
29
+ type: "unsubscribe";
30
+ project_id: string;
31
+ } | {
32
+ type: "ping";
33
+ ts?: number;
34
+ };
35
+ export type OnSprintUpdate = (sprint: Sprint | null) => void;
36
+ export interface WebSocketClientOptions {
37
+ apiUrl: string;
38
+ accessToken: string;
39
+ projectId: string;
40
+ onSprintUpdate: OnSprintUpdate;
41
+ onClose?: () => void;
42
+ onError?: (err: Error) => void;
43
+ }
44
+ /**
45
+ * Open WebSocket to Sprint Planner, subscribe to project, and forward sprint_update.
46
+ */
47
+ export declare function createWebSocketClient(options: WebSocketClientOptions): WebSocket;
48
+ //# sourceMappingURL=websocket-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../src/websocket-client.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;AAE7D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CA+BhF"}
@@ -0,0 +1,33 @@
1
+ import WebSocket from "ws";
2
+ /**
3
+ * Open WebSocket to Sprint Planner, subscribe to project, and forward sprint_update.
4
+ */
5
+ export function createWebSocketClient(options) {
6
+ const { apiUrl, accessToken, projectId, onSprintUpdate, onClose, onError } = options;
7
+ const base = apiUrl.replace(/^http/, "ws").replace(/\/$/, "");
8
+ const wsUrl = `${base}/api/local-agent/ws?token=${encodeURIComponent(accessToken)}`;
9
+ const ws = new WebSocket(wsUrl);
10
+ ws.on("open", () => {
11
+ const msg = { type: "subscribe", project_id: projectId };
12
+ ws.send(JSON.stringify(msg));
13
+ });
14
+ ws.on("message", (data) => {
15
+ try {
16
+ const msg = JSON.parse(data.toString());
17
+ if (msg.type === "sprint_update") {
18
+ onSprintUpdate(msg.sprint);
19
+ }
20
+ }
21
+ catch {
22
+ // ignore malformed
23
+ }
24
+ });
25
+ ws.on("close", () => {
26
+ onClose?.();
27
+ });
28
+ ws.on("error", (err) => {
29
+ onError?.(err);
30
+ });
31
+ return ws;
32
+ }
33
+ //# sourceMappingURL=websocket-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../src/websocket-client.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AA2B3B;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA+B;IACnE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACrF,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,GAAG,IAAI,6BAA6B,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IACpF,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;IAEhC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACjB,MAAM,GAAG,GAAwB,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;QAC9E,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAY,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAwB,CAAC;YAC/D,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACjC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,OAAO,EAAE,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;QAC5B,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC;AACZ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "bobbi-agent",
3
+ "version": "0.1.0",
4
+ "description": "Local Bobbi Agent CLI daemon — syncs Sprint Planner with ./.bobbi/ for AI IDEs",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "bobbi": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "prepare": "npm run build",
21
+ "prepublishOnly": "npm run build",
22
+ "start": "node dist/cli.js start",
23
+ "login": "node dist/cli.js login",
24
+ "dev": "tsc --watch"
25
+ },
26
+ "keywords": [
27
+ "bobbi",
28
+ "sprint",
29
+ "cli",
30
+ "agent",
31
+ "cursor",
32
+ "ai"
33
+ ],
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/Yolxander/bobbi-local-agent.git"
38
+ },
39
+ "homepage": "https://github.com/Yolxander/bobbi-local-agent#readme",
40
+ "bugs": {
41
+ "url": "https://github.com/Yolxander/bobbi-local-agent/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ },
46
+ "dependencies": {
47
+ "chokidar": "^3.6.0",
48
+ "commander": "^12.1.0",
49
+ "dotenv": "^16.4.5",
50
+ "execa": "^9.5.2",
51
+ "node-cron": "^3.0.3",
52
+ "simple-git": "^3.27.0",
53
+ "ws": "^8.18.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^22.10.0",
57
+ "@types/ws": "^8.18.1",
58
+ "typescript": "^5.7.0"
59
+ },
60
+ "files": [
61
+ "dist",
62
+ "templates",
63
+ "README.md",
64
+ "LICENSE"
65
+ ]
66
+ }
@@ -0,0 +1,28 @@
1
+ #!/bin/sh
2
+ # Bobbi post-checkout hook: on branch change, update state and optionally notify cloud.
3
+ # Requires: ./.bobbi/ and state.json
4
+
5
+ BOBBI_DIR="${BOBBI_DIR:-./.bobbi}"
6
+ STATE="$BOBBI_DIR/state.json"
7
+ if [ ! -d "$BOBBI_DIR" ]; then exit 0; fi
8
+
9
+ # Only run for branch checkouts (not file checkouts)
10
+ PREV_HEAD="$1"
11
+ NEW_HEAD="$2"
12
+ BRANCH_CHECKOUT="$3"
13
+ if [ "$BRANCH_CHECKOUT" != "1" ]; then exit 0; fi
14
+
15
+ BRANCH=$(git rev-parse --abbrev-ref HEAD)
16
+ # Update state.json active_branch via node if available
17
+ if command -v node >/dev/null 2>&1; then
18
+ node -e "
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const p = path.resolve(process.cwd(), '$STATE');
22
+ let s = { last_sync_time: new Date().toISOString(), last_commit_hash: '', active_branch: '$BRANCH', sprint_version: '' };
23
+ try { s = { ...s, ...JSON.parse(fs.readFileSync(p, 'utf8')) }; } catch(e) {}
24
+ s.active_branch = '$BRANCH';
25
+ fs.writeFileSync(p, JSON.stringify(s, null, 2));
26
+ " 2>/dev/null || true
27
+ fi
28
+ exit 0
@@ -0,0 +1,27 @@
1
+ #!/bin/sh
2
+ # Bobbi post-commit hook: extract task from commit message and notify Sprint Planner.
3
+ # Requires: BOBBI_DIR or repo root with ./.bobbi/config.json
4
+
5
+ BOBBI_DIR="${BOBBI_DIR:-./.bobbi}"
6
+ CONFIG="$BOBBI_DIR/config.json"
7
+ if [ ! -f "$CONFIG" ]; then exit 0; fi
8
+
9
+ COMMIT_MSG=$(git log -1 --pretty=%B)
10
+ COMMIT_HASH=$(git rev-parse --short HEAD)
11
+ BRANCH=$(git rev-parse --abbrev-ref HEAD)
12
+
13
+ # Extract task id/identifier from message (e.g. "Task 1", "fix: auth-middleware", "01-auth")
14
+ TASK_ID=""
15
+ echo "$COMMIT_MSG" | grep -qEi "task[-\s]*([0-9]+)|([0-9]{2})-([a-z-]+)" && {
16
+ TASK_ID=$(echo "$COMMIT_MSG" | grep -oEi "task[-\s]*[0-9]+|([0-9]{2})-([a-z-]+)" | head -1 | tr -d ' \n')
17
+ }
18
+
19
+ API_URL=$(node -e "try { const c=require('path').resolve(process.cwd(),'$CONFIG'); const j=require('fs').readFileSync(c,'utf8'); const o=JSON.parse(j); console.log(o.api_url||''); } catch(e) { console.log(''); }")
20
+ if [ -z "$API_URL" ]; then exit 0; fi
21
+
22
+ # POST task-progress (optional: use curl if available)
23
+ # curl -s -X POST "$API_URL/api/local-agent/task-progress" \
24
+ # -H "Content-Type: application/json" \
25
+ # -H "Authorization: Bearer $TOKEN" \
26
+ # -d "{\"task_identifier\":\"$TASK_ID\",\"commit_hash\":\"$COMMIT_HASH\",\"branch\":\"$BRANCH\"}"
27
+ exit 0