@openlap/openlap 1.0.0 → 1.0.1

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/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # openlap
2
+
3
+ Product requirements that agents read. Write a lap, agent builds it.
4
+
5
+ A lap is one goal, issues to implement, and verification criteria. Agents pick the next open lap and work through it. When they commit, criteria auto-check via webhook. No dashboard, no CLI -- just the MCP server.
6
+
7
+ Live at [openlap.app](https://openlap.app)
8
+
9
+ ## Install
10
+
11
+ 1. Admin installs the GitHub App (once per org): https://github.com/apps/openlap-app/installations/new
12
+ 2. Add the MCP server:
13
+
14
+ ```bash
15
+ claude mcp add --transport http lap https://openlap.app/mcp
16
+ ```
17
+
18
+ 3. Open Claude Code. First message triggers GitHub login in browser. Done.
19
+
20
+ For project-scoped briefings (filters context to one repo):
21
+
22
+ ```bash
23
+ claude mcp add --transport http --scope project lap "https://openlap.app/mcp?project=owner/repo"
24
+ ```
25
+
26
+ Project scope overrides global when both exist.
27
+
28
+ 4. Register your repo as a project (once per repo):
29
+
30
+ ```
31
+ create_project owner/repo
32
+ ```
33
+
34
+ ## What agents see
35
+
36
+ **Briefings** -- computed context injected into tool descriptions. Agents see project health, the focused lap's unchecked criteria, staleness signals, and priority collisions without calling any tool. Briefings refresh mid-session after mutations.
37
+
38
+ **Laps** -- sorted by priority (0=focus, 1=urgent, 2=high, 3=normal). Agents work on the first open lap. Each lap has a goal, body, and structured criteria.
39
+
40
+ **Criteria** -- verification checks on each lap. Agents prove work by committing with `LAP-NNN #N` in the commit message:
41
+
42
+ ```bash
43
+ git commit -m "LAP-010 #1 #2 add auth middleware"
44
+ ```
45
+
46
+ The GitHub webhook auto-checks the referenced criteria. When all code criteria pass, the lap auto-closes to done. If manual criteria remain (screenshots, design review), the lap moves to review for human verification.
47
+
48
+ **Focus mode** -- set priority=0 on one lap per project. Its unchecked criteria appear in briefings automatically, so agents know what to verify from `tools/list` alone.
49
+
50
+ ## Develop
51
+
52
+ Prerequisites: Go 1.23+, a GitHub App.
53
+
54
+ ```bash
55
+ export BASE_URL=http://localhost:7784
56
+ export DB_PATH=./openlap.db
57
+ cd cmd/anylap && go run .
58
+ ```
59
+
60
+ Local MCP (overrides the remote server):
61
+
62
+ ```bash
63
+ claude mcp add --transport http lap http://localhost:7784/mcp
64
+ ```
65
+
66
+ ## Deploy
67
+
68
+ Hetzner. `sky ship --app openlap-1`. Secrets via `sky deploy --app openlap-1`.
69
+
70
+ ## Architecture
71
+
72
+ ```
73
+ Agent -> MCP (openlap.app/mcp) -> SQLite
74
+ ```
75
+
76
+ One Go binary serves REST API + MCP protocol. OAuth 2.1 with PKCE, chaining to GitHub for identity. GitHub App installation = team boundary. SQLite with Litestream S3 backup.
77
+
78
+ See CLAUDE.md for technical reference.
package/dist/feed.d.ts CHANGED
@@ -11,7 +11,8 @@ export declare class FeedManager {
11
11
  private streams;
12
12
  private seenIds;
13
13
  private callback;
14
- constructor(baseUrl: string, callback: UpdateCallback);
14
+ private getToken;
15
+ constructor(baseUrl: string, callback: UpdateCallback, getToken?: () => string | undefined);
15
16
  /**
16
17
  * Subscribe to a tag's feed if not already subscribed.
17
18
  */
package/dist/feed.js CHANGED
@@ -5,9 +5,11 @@ export class FeedManager {
5
5
  streams = new Map();
6
6
  seenIds = new Set();
7
7
  callback;
8
- constructor(baseUrl, callback) {
8
+ getToken;
9
+ constructor(baseUrl, callback, getToken) {
9
10
  this.baseUrl = baseUrl;
10
11
  this.callback = callback;
12
+ this.getToken = getToken;
11
13
  }
12
14
  /**
13
15
  * Subscribe to a tag's feed if not already subscribed.
@@ -22,7 +24,12 @@ export class FeedManager {
22
24
  }
23
25
  connect(tag, controller) {
24
26
  const url = `${this.baseUrl}/feed/${tag}/sse`;
25
- fetch(url, { signal: controller.signal })
27
+ const headers = {};
28
+ const token = this.getToken?.();
29
+ if (token) {
30
+ headers["Authorization"] = `Bearer ${token}`;
31
+ }
32
+ fetch(url, { headers, signal: controller.signal })
26
33
  .then((res) => {
27
34
  if (!res.ok || !res.body) {
28
35
  throw new Error(`SSE connect failed: ${res.status}`);
package/dist/proxy.js CHANGED
@@ -3,10 +3,13 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
3
3
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
4
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
5
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
6
+ import { readFileSync } from "fs";
7
+ import { join } from "path";
8
+ import { homedir } from "os";
6
9
  import { FileOAuthProvider } from "./auth.js";
7
10
  import { detectProject, autoSave } from "./git.js";
8
11
  import { FeedManager } from "./feed.js";
9
- const BASE_URL = process.env.ANYLAP_URL ?? "https://openlap.app";
12
+ const BASE_URL = process.env.OPENLAP_URL ?? "https://openlap.app";
10
13
  // Tools that accept a 'project' parameter
11
14
  const PROJECT_TOOLS = new Set([
12
15
  "list_laps", "get_lap", "create_lap", "save_lap", "update_lap",
@@ -70,6 +73,15 @@ export async function startProxy() {
70
73
  process.stderr.write(`[openlap] notification error: ${err}\n`);
71
74
  }
72
75
  });
76
+ }, () => {
77
+ // Provide auth token for SSE feed connections
78
+ try {
79
+ const data = JSON.parse(readFileSync(join(homedir(), ".openlap", "auth.json"), "utf-8"));
80
+ return data?.tokens?.access_token;
81
+ }
82
+ catch {
83
+ return undefined;
84
+ }
73
85
  });
74
86
  // Forward tool listing from remote
75
87
  server.setRequestHandler(ListToolsRequestSchema, async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openlap/openlap",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Local MCP proxy for openlap.app -- auto-save, live feeds, project detection, one install",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",