lockstep-cli 0.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.
Files changed (70) hide show
  1. package/dist/adapters/claude.d.ts +2 -0
  2. package/dist/adapters/claude.js +56 -0
  3. package/dist/adapters/claude.js.map +1 -0
  4. package/dist/adapters/fsutil.d.ts +7 -0
  5. package/dist/adapters/fsutil.js +41 -0
  6. package/dist/adapters/fsutil.js.map +1 -0
  7. package/dist/adapters/install.test.d.ts +1 -0
  8. package/dist/adapters/install.test.js +32 -0
  9. package/dist/adapters/install.test.js.map +1 -0
  10. package/dist/adapters/merge.d.ts +27 -0
  11. package/dist/adapters/merge.js +49 -0
  12. package/dist/adapters/merge.js.map +1 -0
  13. package/dist/adapters/merge.test.d.ts +1 -0
  14. package/dist/adapters/merge.test.js +41 -0
  15. package/dist/adapters/merge.test.js.map +1 -0
  16. package/dist/adapters/registry.d.ts +2 -0
  17. package/dist/adapters/registry.js +17 -0
  18. package/dist/adapters/registry.js.map +1 -0
  19. package/dist/adapters/templates.d.ts +5 -0
  20. package/dist/adapters/templates.js +40 -0
  21. package/dist/adapters/templates.js.map +1 -0
  22. package/dist/adapters/types.d.ts +14 -0
  23. package/dist/adapters/types.js +2 -0
  24. package/dist/adapters/types.js.map +1 -0
  25. package/dist/auth/token-store.d.ts +3 -0
  26. package/dist/auth/token-store.js +74 -0
  27. package/dist/auth/token-store.js.map +1 -0
  28. package/dist/capture/classify.d.ts +12 -0
  29. package/dist/capture/classify.js +26 -0
  30. package/dist/capture/classify.js.map +1 -0
  31. package/dist/capture/classify.test.d.ts +1 -0
  32. package/dist/capture/classify.test.js +25 -0
  33. package/dist/capture/classify.test.js.map +1 -0
  34. package/dist/capture/diff.d.ts +2 -0
  35. package/dist/capture/diff.js +19 -0
  36. package/dist/capture/diff.js.map +1 -0
  37. package/dist/capture/index.d.ts +6 -0
  38. package/dist/capture/index.js +85 -0
  39. package/dist/capture/index.js.map +1 -0
  40. package/dist/cloud.d.ts +8 -0
  41. package/dist/cloud.js +38 -0
  42. package/dist/cloud.js.map +1 -0
  43. package/dist/config.d.ts +8 -0
  44. package/dist/config.js +26 -0
  45. package/dist/config.js.map +1 -0
  46. package/dist/connect.d.ts +10 -0
  47. package/dist/connect.js +60 -0
  48. package/dist/connect.js.map +1 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.js +98 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/init.d.ts +8 -0
  53. package/dist/init.js +46 -0
  54. package/dist/init.js.map +1 -0
  55. package/dist/login.d.ts +6 -0
  56. package/dist/login.js +32 -0
  57. package/dist/login.js.map +1 -0
  58. package/dist/mcp/api.d.ts +2 -0
  59. package/dist/mcp/api.js +22 -0
  60. package/dist/mcp/api.js.map +1 -0
  61. package/dist/mcp/git.d.ts +3 -0
  62. package/dist/mcp/git.js +20 -0
  63. package/dist/mcp/git.js.map +1 -0
  64. package/dist/mcp/server.d.ts +6 -0
  65. package/dist/mcp/server.js +39 -0
  66. package/dist/mcp/server.js.map +1 -0
  67. package/dist/mcp/session.d.ts +9 -0
  68. package/dist/mcp/session.js +12 -0
  69. package/dist/mcp/session.js.map +1 -0
  70. package/package.json +43 -0
@@ -0,0 +1,85 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { registerSession } from "../mcp/session.js";
5
+ import { call } from "../mcp/api.js";
6
+ import { changedFiles } from "./diff.js";
7
+ import { isContractSurface, riskTierFor } from "./classify.js";
8
+ function formatReplay(inbox, decisions) {
9
+ const lines = [];
10
+ const changes = inbox?.changes ?? [];
11
+ if (changes.length) {
12
+ lines.push(`๐Ÿ“ฅ ${changes.length} change(s) since you were last here:`);
13
+ for (const c of changes.slice(0, 8))
14
+ lines.push(` โ€ข ${c.summary}${c.surface ? ` (${c.surface})` : ""}`);
15
+ }
16
+ const binding = (decisions?.decisions ?? []).filter((d) => d.status === "binding");
17
+ if (binding.length) {
18
+ lines.push(`๐Ÿ“Œ ${binding.length} binding decision(s) in effect:`);
19
+ for (const d of binding.slice(0, 8))
20
+ lines.push(` โ€ข [${d.scopeRef}] ${d.ruleText}`);
21
+ }
22
+ return lines.length ? `Lockstep:\n${lines.join("\n")}` : "Lockstep: nothing new.";
23
+ }
24
+ /**
25
+ * Hook entrypoint. Resilient by design โ€” never break the agent: on any error it exits 0.
26
+ * SessionStart โ†’ replay inbox + binding decisions as additionalContext.
27
+ * PostToolUse/Stop โ†’ diff โ†’ classify surface โ†’ risk-tiered publish via notify.
28
+ */
29
+ export async function runCapture(event) {
30
+ const vendor = process.env.LOCKSTEP_VENDOR ?? "unknown";
31
+ const cwd = process.cwd();
32
+ let session;
33
+ try {
34
+ session = await registerSession(vendor);
35
+ }
36
+ catch {
37
+ process.exit(0); // not a connected repo / not logged in โ†’ silent no-op
38
+ }
39
+ try {
40
+ if (event === "SessionStart") {
41
+ const inbox = await call("GET", "/inbox", session.sessionId).catch(() => null);
42
+ const decisions = await call("GET", "/decisions", session.sessionId).catch(() => null);
43
+ process.stdout.write(JSON.stringify({
44
+ hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: formatReplay(inbox, decisions) },
45
+ }));
46
+ return;
47
+ }
48
+ // PostToolUse / Stop โ€” capture the change
49
+ const files = changedFiles(cwd);
50
+ if (files.length === 0)
51
+ return;
52
+ const surfaces = [];
53
+ let anyContractSurface = false;
54
+ for (const f of files) {
55
+ let content = "";
56
+ try {
57
+ content = readFileSync(join(cwd, f), "utf8");
58
+ }
59
+ catch {
60
+ /* deleted/binary โ€” skip content */
61
+ }
62
+ if (isContractSurface(f, content)) {
63
+ anyContractSurface = true;
64
+ surfaces.push(f);
65
+ }
66
+ }
67
+ // v1: contract surface โ‡’ shared (the safety-critical bias). Ownership-based refinement later.
68
+ const riskTier = riskTierFor({ anyContractSurface, allOwnedByMe: true });
69
+ const summary = `${event}: changed ${files.length} file(s): ${files.slice(0, 5).join(", ")}${files.length > 5 ? "โ€ฆ" : ""}`;
70
+ const diffHash = createHash("sha256").update(files.sort().join("|")).digest("hex").slice(0, 16);
71
+ await call("POST", "/changes", session.sessionId, {
72
+ summary,
73
+ surface: surfaces[0],
74
+ riskTier,
75
+ verified: true, // mechanical delta is derived from real local code
76
+ verifiedAgainst: "git-diff",
77
+ diffHash,
78
+ }).catch(() => { });
79
+ process.stderr.write(`[lockstep] published change (${riskTier})\n`);
80
+ }
81
+ catch {
82
+ process.exit(0);
83
+ }
84
+ }
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** Thin authed HTTP client to the core API. Reads the server from config/env each call. */
2
+ export declare const cloud: {
3
+ readonly apiUrl: string;
4
+ get: <T = unknown>(p: string) => Promise<T>;
5
+ post: <T = unknown>(p: string, b?: unknown) => Promise<T>;
6
+ patch: <T = unknown>(p: string, b?: unknown) => Promise<T>;
7
+ del: <T = unknown>(p: string) => Promise<T>;
8
+ };
package/dist/cloud.js ADDED
@@ -0,0 +1,38 @@
1
+ import { getToken } from "./auth/token-store.js";
2
+ import { resolveApiUrl } from "./config.js";
3
+ async function req(method, path, body) {
4
+ const API = resolveApiUrl();
5
+ const token = await getToken();
6
+ let res;
7
+ try {
8
+ res = await fetch(`${API}${path}`, {
9
+ method,
10
+ headers: {
11
+ ...(body === undefined ? {} : { "content-type": "application/json" }),
12
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
13
+ },
14
+ body: body === undefined ? undefined : JSON.stringify(body),
15
+ });
16
+ }
17
+ catch {
18
+ throw new Error(`Cannot reach the Lockstep API at ${API}\n` +
19
+ `Set your server once with: lockstep login --api <url>`);
20
+ }
21
+ const text = await res.text();
22
+ const json = text ? JSON.parse(text) : null;
23
+ if (!res.ok) {
24
+ throw new Error(`${method} ${path} โ†’ ${res.status}: ${text || res.statusText}`);
25
+ }
26
+ return json;
27
+ }
28
+ /** Thin authed HTTP client to the core API. Reads the server from config/env each call. */
29
+ export const cloud = {
30
+ get apiUrl() {
31
+ return resolveApiUrl();
32
+ },
33
+ get: (p) => req("GET", p),
34
+ post: (p, b) => req("POST", p, b),
35
+ patch: (p, b) => req("PATCH", p, b),
36
+ del: (p) => req("DELETE", p),
37
+ };
38
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,KAAK,UAAU,GAAG,CAAc,MAAc,EAAE,IAAY,EAAE,IAAc;IAC1E,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE;YACjC,MAAM;YACN,OAAO,EAAE;gBACP,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;gBACrE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACvD;YACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC5D,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,oCAAoC,GAAG,IAAI;YACzC,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,CAAC,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,IAAS,CAAC;AACnB,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,MAAM;QACR,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IACD,GAAG,EAAE,CAAc,CAAS,EAAE,EAAE,CAAC,GAAG,CAAI,KAAK,EAAE,CAAC,CAAC;IACjD,IAAI,EAAE,CAAc,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAI,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACnE,KAAK,EAAE,CAAc,CAAS,EAAE,CAAW,EAAE,EAAE,CAAC,GAAG,CAAI,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACrE,GAAG,EAAE,CAAc,CAAS,EAAE,EAAE,CAAC,GAAG,CAAI,QAAQ,EAAE,CAAC,CAAC;CACrD,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface Config {
2
+ apiUrl?: string;
3
+ }
4
+ export declare function getConfig(): Config;
5
+ export declare function setApiUrl(apiUrl: string): void;
6
+ /** Resolution order: env var โ†’ saved config โ†’ default. Trailing slash stripped. */
7
+ export declare function resolveApiUrl(): string;
8
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,26 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
4
+ /** Persisted CLI config (~/.lockstep/config.json) so users set the API once, not every shell. */
5
+ const dir = join(homedir(), ".lockstep");
6
+ const path = join(dir, "config.json");
7
+ export function getConfig() {
8
+ try {
9
+ return JSON.parse(readFileSync(path, "utf8"));
10
+ }
11
+ catch {
12
+ return {};
13
+ }
14
+ }
15
+ export function setApiUrl(apiUrl) {
16
+ mkdirSync(dir, { recursive: true });
17
+ const c = getConfig();
18
+ c.apiUrl = apiUrl.replace(/\/+$/, "");
19
+ writeFileSync(path, JSON.stringify(c, null, 2), { mode: 0o600 });
20
+ }
21
+ /** Resolution order: env var โ†’ saved config โ†’ default. Trailing slash stripped. */
22
+ export function resolveApiUrl() {
23
+ const raw = process.env.LOCKSTEP_API_URL || getConfig().apiUrl || "http://localhost:8080";
24
+ return raw.replace(/\/+$/, "");
25
+ }
26
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEjE,iGAAiG;AACjG,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACzC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AAMtC,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAW,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;IACtB,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,SAAS,EAAE,CAAC,MAAM,IAAI,uBAAuB,CAAC;IAC1F,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Connect the current repo to a Lockstep project so agent sessions can register.
3
+ * Creates an org/project on first use. Idempotent โ€” re-running is a no-op.
4
+ */
5
+ export declare function runConnect(opts: {
6
+ org?: string;
7
+ project?: string;
8
+ }): Promise<void>;
9
+ /** Invite a teammate by GitHub handle to this repo's project. */
10
+ export declare function runInvite(handle: string): Promise<void>;
@@ -0,0 +1,60 @@
1
+ import { cloud } from "./cloud.js";
2
+ import { gitRemote } from "./mcp/git.js";
3
+ /**
4
+ * Connect the current repo to a Lockstep project so agent sessions can register.
5
+ * Creates an org/project on first use. Idempotent โ€” re-running is a no-op.
6
+ */
7
+ export async function runConnect(opts) {
8
+ const remote = gitRemote(process.cwd());
9
+ if (!remote) {
10
+ console.error("No git 'origin' remote here โ€” Lockstep identifies a repo by its remote.");
11
+ process.exit(1);
12
+ }
13
+ const me = await cloud.get("/me");
14
+ let orgId = me.memberships[0]?.orgId;
15
+ if (!orgId) {
16
+ const created = await cloud.post("/orgs", {
17
+ name: opts.org ?? `${me.principal.githubLogin}'s workspace`,
18
+ });
19
+ orgId = created.orgId;
20
+ }
21
+ const projectName = opts.project ?? remote.split("/").pop() ?? "default";
22
+ const overview = await cloud.get(`/orgs/${orgId}/overview`);
23
+ let projectId = overview?.projects.find((p) => p.name === projectName)?.id;
24
+ if (!projectId) {
25
+ projectId = (await cloud.post(`/orgs/${orgId}/projects`, { name: projectName })).projectId;
26
+ }
27
+ const po = await cloud.get(`/orgs/${orgId}/projects/${projectId}/overview`);
28
+ const already = po?.repos.some((r) => r.gitRemote === remote);
29
+ if (!already) {
30
+ await cloud.post(`/orgs/${orgId}/projects/${projectId}/repos`, { gitRemote: remote });
31
+ }
32
+ console.log(`โœ“ connected ${remote}`);
33
+ console.log(` โ†’ project "${projectName}" (org ${orgId.slice(0, 8)})`);
34
+ console.log(`\nOpen this repo in Claude Code โ€” Lockstep registers the session automatically.`);
35
+ console.log(`Invite a teammate: lockstep invite <github-handle> (or via the dashboard)`);
36
+ }
37
+ /** Invite a teammate by GitHub handle to this repo's project. */
38
+ export async function runInvite(handle) {
39
+ const remote = gitRemote(process.cwd());
40
+ if (!remote) {
41
+ console.error("Run this inside a connected repo.");
42
+ process.exit(1);
43
+ }
44
+ const me = await cloud.get("/me");
45
+ const orgId = me.memberships[0]?.orgId;
46
+ if (!orgId) {
47
+ console.error("No workspace yet โ€” run `lockstep connect` first.");
48
+ process.exit(1);
49
+ }
50
+ const projectName = remote.split("/").pop() ?? "default";
51
+ const overview = await cloud.get(`/orgs/${orgId}/overview`);
52
+ const projectId = overview?.projects.find((p) => p.name === projectName)?.id;
53
+ if (!projectId) {
54
+ console.error("This repo isn't connected yet โ€” run `lockstep connect` first.");
55
+ process.exit(1);
56
+ }
57
+ await cloud.post(`/orgs/${orgId}/projects/${projectId}/invite`, { githubLogin: handle.replace(/^@/, "") });
58
+ console.log(`โœ“ invited @${handle.replace(/^@/, "")} to "${projectName}" โ€” they'll be activated on their next login.`);
59
+ }
60
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import { runInit, runStatus, runDoctor } from "./init.js";
3
+ import { runLogin } from "./login.js";
4
+ import { runConnect, runInvite } from "./connect.js";
5
+ const argv = process.argv.slice(2);
6
+ const cmd = argv[0];
7
+ const has = (n) => argv.includes(`--${n}`);
8
+ const val = (n) => {
9
+ const i = argv.indexOf(`--${n}`);
10
+ return i >= 0 ? argv[i + 1] : undefined;
11
+ };
12
+ function help() {
13
+ console.log(`lockstep โ€” keep your team's coding agents in sync
14
+
15
+ usage: lockstep <command>
16
+
17
+ login [--api <url>] [--dev --dev-id <n> --dev-login <handle>]
18
+ authenticate; --api saves your server (once), --dev for testing
19
+ init [--vendor claude|all] [--scope project|user] [--dry-run]
20
+ wire up hooks + MCP + skill for the detected agent(s)
21
+ connect [--project <name>] link this repo to a Lockstep project (creates one if needed)
22
+ invite <github-handle> invite a teammate to this repo's project
23
+ status show auth + config health
24
+ doctor diagnose vendor config
25
+ mcp run the per-session MCP server (used by agents)
26
+ capture --event <E> hook entrypoint (used by hooks) [P6]
27
+ `);
28
+ }
29
+ function notYet(name, phase) {
30
+ console.error(`\`lockstep ${name}\` is not implemented yet (arrives in ${phase}).`);
31
+ process.exit(2);
32
+ }
33
+ async function main() {
34
+ switch (cmd) {
35
+ case "login": {
36
+ // Remember the server so the user never has to export anything again.
37
+ const api = val("api") ?? process.env.LOCKSTEP_API_URL;
38
+ if (api) {
39
+ const { setApiUrl } = await import("./config.js");
40
+ setApiUrl(api);
41
+ }
42
+ if (has("dev")) {
43
+ const id = Number(val("dev-id") ?? "0");
44
+ const login = val("dev-login") ?? "";
45
+ if (!id || !login) {
46
+ console.error("usage: lockstep login --dev --dev-id <n> --dev-login <handle>");
47
+ process.exit(1);
48
+ }
49
+ return runLogin({ dev: { id, login } });
50
+ }
51
+ return runLogin({});
52
+ }
53
+ case "init":
54
+ return runInit({
55
+ vendor: val("vendor"),
56
+ scope: val("scope") ?? "project",
57
+ dryRun: has("dry-run"),
58
+ });
59
+ case "connect":
60
+ return runConnect({ org: val("org"), project: val("project") });
61
+ case "invite": {
62
+ const handle = argv[1];
63
+ if (!handle) {
64
+ console.error("usage: lockstep invite <github-handle>");
65
+ process.exit(1);
66
+ }
67
+ return runInvite(handle);
68
+ }
69
+ case "status":
70
+ return runStatus();
71
+ case "doctor":
72
+ return runDoctor();
73
+ case "mcp": {
74
+ const { runMcpServer } = await import("./mcp/server.js");
75
+ await runMcpServer();
76
+ return;
77
+ }
78
+ case "capture": {
79
+ const { runCapture } = await import("./capture/index.js");
80
+ await runCapture(val("event") ?? "PostToolUse");
81
+ return;
82
+ }
83
+ case "help":
84
+ case "--help":
85
+ case "-h":
86
+ case undefined:
87
+ return help();
88
+ default:
89
+ console.error(`unknown command: ${cmd}\n`);
90
+ help();
91
+ process.exit(1);
92
+ }
93
+ }
94
+ void main().catch((e) => {
95
+ console.error(e instanceof Error ? e.message : e);
96
+ process.exit(1);
97
+ });
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Scope } from "./adapters/types.js";
2
+ export declare function runInit(opts: {
3
+ vendor?: string;
4
+ scope: Scope;
5
+ dryRun: boolean;
6
+ }): Promise<void>;
7
+ export declare function runStatus(): Promise<void>;
8
+ export declare function runDoctor(): Promise<void>;
package/dist/init.js ADDED
@@ -0,0 +1,46 @@
1
+ import { getAdapters } from "./adapters/registry.js";
2
+ import { cloud } from "./cloud.js";
3
+ import { getToken } from "./auth/token-store.js";
4
+ export async function runInit(opts) {
5
+ const cwd = process.cwd();
6
+ const adapters = await getAdapters(opts.vendor);
7
+ if (adapters.length === 0) {
8
+ console.error(`no adapter for vendor: ${opts.vendor}`);
9
+ process.exit(1);
10
+ }
11
+ console.log(`lockstep init โ€” scope=${opts.scope}${opts.dryRun ? " (dry-run)" : ""}`);
12
+ for (const a of adapters) {
13
+ console.log(`\n[${a.id}]`);
14
+ for (const line of await a.install(cwd, opts.scope, opts.dryRun)) {
15
+ console.log(" " + line);
16
+ }
17
+ }
18
+ if (!opts.dryRun && opts.scope === "project") {
19
+ console.log("\nCommit the written files so teammates get Lockstep automatically on clone.");
20
+ }
21
+ }
22
+ export async function runStatus() {
23
+ console.log(`api: ${cloud.apiUrl}`);
24
+ console.log(`auth: ${(await getToken()) ? "logged in" : "not logged in (run: lockstep login)"}`);
25
+ const cwd = process.cwd();
26
+ for (const a of await getAdapters()) {
27
+ const v = await a.verify(cwd, "project");
28
+ console.log(`\n[${a.id}] ${v.ok ? "configured" : "not configured"}`);
29
+ for (const d of v.details)
30
+ console.log(" " + d);
31
+ }
32
+ }
33
+ export async function runDoctor() {
34
+ const cwd = process.cwd();
35
+ let ok = true;
36
+ for (const a of await getAdapters()) {
37
+ const v = await a.verify(cwd, "project");
38
+ if (!v.ok)
39
+ ok = false;
40
+ console.log(`[${a.id}] ${v.ok ? "OK" : "PROBLEM"}`);
41
+ for (const d of v.details)
42
+ console.log(" " + d);
43
+ }
44
+ process.exit(ok ? 0 : 1);
45
+ }
46
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function runLogin(opts: {
2
+ dev?: {
3
+ id: number;
4
+ login: string;
5
+ };
6
+ }): Promise<void>;
package/dist/login.js ADDED
@@ -0,0 +1,32 @@
1
+ import { cloud } from "./cloud.js";
2
+ import { setToken } from "./auth/token-store.js";
3
+ export async function runLogin(opts) {
4
+ if (opts.dev) {
5
+ const r = await cloud.post("/auth/dev-login", {
6
+ githubUserId: opts.dev.id,
7
+ githubLogin: opts.dev.login,
8
+ });
9
+ if (!r.token)
10
+ throw new Error("dev-login failed (is LOCKSTEP_DEV_LOGIN enabled on the server?)");
11
+ await setToken(r.token);
12
+ console.log(`logged in as ${r.githubLogin} (dev)`);
13
+ return;
14
+ }
15
+ const start = await cloud.post("/auth/device/start");
16
+ console.log(`\nOpen ${start.verification_uri} and enter code: ${start.user_code}\n`);
17
+ const interval = (start.interval ?? 5) * 1000;
18
+ for (;;) {
19
+ await new Promise((r) => setTimeout(r, interval));
20
+ const poll = await cloud.post("/auth/device/poll", { device_code: start.device_code });
21
+ if (poll.status === "ok" && poll.token) {
22
+ await setToken(poll.token);
23
+ console.log(`logged in as ${poll.githubLogin}`);
24
+ return;
25
+ }
26
+ if (poll.error && poll.error !== "authorization_pending" && poll.error !== "slow_down") {
27
+ console.error(`login failed: ${poll.error}`);
28
+ process.exit(1);
29
+ }
30
+ }
31
+ }
32
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AASjD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAA6C;IAC1E,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,CAAY,iBAAiB,EAAE;YACvD,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE;YACzB,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACjG,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,WAAW,QAAQ,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAC5B,oBAAoB,CACrB,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,gBAAgB,qBAAqB,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9C,SAAS,CAAC;QACR,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAY,mBAAmB,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAClG,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,uBAAuB,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACvF,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Session-aware authed request: attaches the bearer token and the x-lockstep-session header. */
2
+ export declare function call<T = unknown>(method: string, path: string, sessionId: string | undefined, body?: unknown): Promise<T>;
@@ -0,0 +1,22 @@
1
+ import { getToken } from "../auth/token-store.js";
2
+ import { resolveApiUrl } from "../config.js";
3
+ /** Session-aware authed request: attaches the bearer token and the x-lockstep-session header. */
4
+ export async function call(method, path, sessionId, body) {
5
+ const API = resolveApiUrl();
6
+ const token = await getToken();
7
+ const res = await fetch(`${API}${path}`, {
8
+ method,
9
+ headers: {
10
+ ...(body === undefined ? {} : { "content-type": "application/json" }),
11
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
12
+ ...(sessionId ? { "x-lockstep-session": sessionId } : {}),
13
+ },
14
+ body: body === undefined ? undefined : JSON.stringify(body),
15
+ });
16
+ const text = await res.text();
17
+ const json = text ? JSON.parse(text) : null;
18
+ if (!res.ok)
19
+ throw new Error(`${method} ${path} โ†’ ${res.status}: ${text || res.statusText}`);
20
+ return json;
21
+ }
22
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/mcp/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,MAAc,EACd,IAAY,EACZ,SAA6B,EAC7B,IAAc;IAEd,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE;QACvC,MAAM;QACN,OAAO,EAAE;YACP,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YACrE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1D;QACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC5D,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,IAAI,MAAM,GAAG,CAAC,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7F,OAAO,IAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Canonicalize a git remote URL to `host/org/repo` โ€” the session match key (PRD ยง8). */
2
+ export declare function normalizeRemote(url: string): string;
3
+ export declare function gitRemote(cwd: string): string | null;
@@ -0,0 +1,20 @@
1
+ import { execFileSync } from "node:child_process";
2
+ /** Canonicalize a git remote URL to `host/org/repo` โ€” the session match key (PRD ยง8). */
3
+ export function normalizeRemote(url) {
4
+ let u = url.trim();
5
+ u = u.replace(/^git@([^:]+):/, "$1/"); // git@github.com:org/repo(.git) โ†’ github.com/org/repo
6
+ u = u.replace(/^[a-z]+:\/\//, ""); // strip scheme
7
+ u = u.replace(/^[^@/]+@/, ""); // strip user@ (https with creds)
8
+ u = u.replace(/\.git$/, "");
9
+ return u;
10
+ }
11
+ export function gitRemote(cwd) {
12
+ try {
13
+ const out = execFileSync("git", ["-C", cwd, "remote", "get-url", "origin"], { encoding: "utf8" });
14
+ return normalizeRemote(out);
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/mcp/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,yFAAyF;AACzF,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC,sDAAsD;IAC7F,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe;IAClD,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,iCAAiC;IAChE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAClG,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The per-session MCP server (one process per agent session). Registers the session,
3
+ * then exposes the 12 tools as thin proxies to the core API. The core stays LLM-free โ€”
4
+ * query() returns rows; the agent synthesizes. Identical across vendors (the seam).
5
+ */
6
+ export declare function runMcpServer(): Promise<void>;
@@ -0,0 +1,39 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ import { registerSession } from "./session.js";
5
+ import { call } from "./api.js";
6
+ /**
7
+ * The per-session MCP server (one process per agent session). Registers the session,
8
+ * then exposes the 12 tools as thin proxies to the core API. The core stays LLM-free โ€”
9
+ * query() returns rows; the agent synthesizes. Identical across vendors (the seam).
10
+ */
11
+ export async function runMcpServer() {
12
+ const vendor = process.env.LOCKSTEP_VENDOR ?? "unknown";
13
+ const session = await registerSession(vendor); // stderr-safe: throws to caller on failure
14
+ const sid = session.sessionId;
15
+ const ok = (data) => ({ content: [{ type: "text", text: JSON.stringify(data) }] });
16
+ const server = new McpServer({ name: "lockstep", version: "0.0.1" });
17
+ server.tool("notify", {
18
+ summary: z.string(),
19
+ surface: z.string().optional(),
20
+ contractDelta: z.any().optional(),
21
+ riskTier: z.enum(["owned", "shared", "contract"]).optional(),
22
+ verified: z.boolean().optional(),
23
+ verifiedAgainst: z.string().optional(),
24
+ diffHash: z.string().optional(),
25
+ }, async (a) => ok(await call("POST", "/changes", sid, a)));
26
+ server.tool("inbox", {}, async () => ok(await call("GET", "/inbox", sid)));
27
+ server.tool("query", { question: z.string(), scope: z.string().optional() }, async (a) => ok(await call("POST", "/query", sid, a)));
28
+ server.tool("ask", { question: z.string(), scope: z.string().optional(), urgent: z.boolean().optional() }, async (a) => ok(await call("POST", "/questions", sid, a)));
29
+ server.tool("answer", { questionId: z.string(), response: z.string() }, async (a) => ok(await call("POST", `/questions/${a.questionId}/answer`, sid, { response: a.response })));
30
+ server.tool("delegate", { to: z.string(), task: z.string(), refs: z.any().optional() }, async (a) => ok(await call("POST", "/tasks", sid, a)));
31
+ server.tool("complete", { taskId: z.string(), note: z.string().optional() }, async (a) => ok(await call("POST", `/tasks/${a.taskId}/complete`, sid, { note: a.note })));
32
+ server.tool("propose_decision", { scopeKind: z.string(), scopeRef: z.string(), ruleText: z.string(), baseVersion: z.number() }, async (a) => ok(await call("POST", "/decisions", sid, a)));
33
+ server.tool("ack_decision", { decisionId: z.string(), version: z.number(), verdict: z.string().optional() }, async (a) => ok(await call("POST", `/decisions/${a.decisionId}/ack`, sid, { version: a.version, verdict: a.verdict })));
34
+ server.tool("register_dependency", { producedSurface: z.string(), producedRepoId: z.string().optional() }, async (a) => ok(await call("POST", "/dependencies", sid, a)));
35
+ server.tool("decisions", { scope: z.string().optional() }, async (a) => ok(await call("GET", `/decisions${a.scope ? `?scope=${encodeURIComponent(a.scope)}` : ""}`, sid)));
36
+ server.tool("whoowns", { path: z.string() }, async (a) => ok(await call("GET", `/owners?path=${encodeURIComponent(a.path)}`, sid)));
37
+ await server.connect(new StdioServerTransport());
38
+ }
39
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface Session {
2
+ sessionId: string;
3
+ orgId: string;
4
+ projectId: string;
5
+ repoId: string;
6
+ memberId: string;
7
+ }
8
+ /** Register this agent session: cwd + git remote โ†’ (user, repo, project). */
9
+ export declare function registerSession(vendor: string): Promise<Session>;