@insitue/claude-plugin 0.7.0 → 0.7.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insitue",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Drive a Claude Code session from the InSitue browser overlay. Pick an element in your app, claude reads the file and proposes the edit.",
5
5
  "mcpServers": {
6
6
  "insitue": {
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @insitue/claude-plugin
2
2
 
3
+ ## 0.7.1
4
+
5
+ - **`/insitue:logout`.** New slash command (+ `logout` MCP tool + `npx @insitue/claude-plugin logout` CLI) that signs you out properly: it revokes this machine's token server-side, then clears the local credentials (`~/.insitue/auth.json`). Revoke is best-effort — your local creds are always cleared even if the network call fails. Pairs with the existing `/insitue:login`.
6
+
3
7
  ## 0.7.0
4
8
 
5
9
  - **Live picks without blocking the chat (channels, opt-in preview).** The MCP server now also PUSHES each pick as a Claude Code channel event (`notifications/claude/channel`). Start your session with `claude --dangerously-load-development-channels --channels plugin:insitue` and picks wake the idle agent instead of you waiting on a poll — the chat stays free for conversation the rest of the time. Plain `claude` + `/insitue:connect` is unchanged (8s poll fallback). The agent de-dupes by pick id, so the push + poll paths never double-handle a pick. Channels are a Claude Code research-preview feature (CLI-only); the flag is required during the preview.
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: Sign out of InSitue Cloud — revokes this machine's token and clears local credentials.
3
+ ---
4
+
5
+ # /insitue:logout
6
+
7
+ Signs you out of InSitue Cloud. Revokes this machine's token server-side
8
+ and removes local credentials from `~/.insitue/auth.json`.
9
+ Even if the server-side revoke fails (network issue, expired token), local
10
+ credentials are always cleared.
11
+
12
+ ## Your behaviour
13
+
14
+ 1. Call `mcp__insitue__logout` (no arguments).
15
+
16
+ 2. On `{ status: "ok", revoked: true }`:
17
+ Reply in one line: "Signed out of InSitue."
18
+
19
+ 3. On `{ status: "ok", revoked: false }`:
20
+ Reply in one line: "Signed out of InSitue. (Token revoke skipped — no token was stored or the server was unreachable, but local credentials have been cleared.)"
21
+
22
+ 4. On any unexpected error: relay the `message` field and suggest running
23
+ `/insitue:logout` again or clearing `~/.insitue/auth.json` manually.
24
+
25
+ ## Notes
26
+
27
+ - Logout always clears local credentials, even when the network revoke fails.
28
+ - To sign back in, run `/insitue:login`.
@@ -40,6 +40,21 @@ function saveAuth(patch) {
40
40
  mode: 384
41
41
  });
42
42
  }
43
+ function clearAuth() {
44
+ const p = join(homedir(), ".insitue", "auth.json");
45
+ if (!existsSync(p)) return;
46
+ let existing = {};
47
+ try {
48
+ existing = JSON.parse(readFileSync(p, "utf8"));
49
+ } catch {
50
+ }
51
+ const cleared = {};
52
+ if (existing.host) cleared.host = existing.host;
53
+ writeFileSync(p, JSON.stringify(cleared, null, 2) + "\n", {
54
+ encoding: "utf8",
55
+ mode: 384
56
+ });
57
+ }
43
58
  function saveProjectLink(projectDir, projectId) {
44
59
  const dir = join(projectDir, ".insitue");
45
60
  mkdirSync(dir, { recursive: true });
@@ -55,5 +70,6 @@ export {
55
70
  loadProjectId,
56
71
  resolveHost,
57
72
  saveAuth,
73
+ clearAuth,
58
74
  saveProjectLink
59
75
  };
@@ -56,11 +56,18 @@ var releaseIssue = (host, token, id) => call(
56
56
  "POST",
57
57
  `/api/v1/dev/issues/${encodeURIComponent(id)}/release`
58
58
  );
59
+ var revokeToken = (host, token) => call(
60
+ host,
61
+ token,
62
+ "POST",
63
+ `/api/v1/dev/token/revoke`
64
+ );
59
65
 
60
66
  export {
61
67
  CloudApiError,
62
68
  listIssues,
63
69
  claimIssue,
64
70
  resolveIssue,
65
- releaseIssue
71
+ releaseIssue,
72
+ revokeToken
66
73
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadAuth,
3
3
  loadProjectId
4
- } from "./chunk-B3HSTDGI.js";
4
+ } from "./chunk-EDGPZTOV.js";
5
5
 
6
6
  // src/diagnose.ts
7
7
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
package/dist/cloud/api.js CHANGED
@@ -3,12 +3,14 @@ import {
3
3
  claimIssue,
4
4
  listIssues,
5
5
  releaseIssue,
6
- resolveIssue
7
- } from "../chunk-IRPBZWNQ.js";
6
+ resolveIssue,
7
+ revokeToken
8
+ } from "../chunk-ESW573VH.js";
8
9
  export {
9
10
  CloudApiError,
10
11
  claimIssue,
11
12
  listIssues,
12
13
  releaseIssue,
13
- resolveIssue
14
+ resolveIssue,
15
+ revokeToken
14
16
  };
@@ -1,11 +1,13 @@
1
1
  import {
2
+ clearAuth,
2
3
  loadAuth,
3
4
  loadProjectId,
4
5
  resolveHost,
5
6
  saveAuth,
6
7
  saveProjectLink
7
- } from "../chunk-B3HSTDGI.js";
8
+ } from "../chunk-EDGPZTOV.js";
8
9
  export {
10
+ clearAuth,
9
11
  loadAuth,
10
12
  loadProjectId,
11
13
  resolveHost,
package/dist/cloud-cli.js CHANGED
@@ -2,12 +2,16 @@ import {
2
2
  resolveProjectDir
3
3
  } from "./chunk-UNMH2DN4.js";
4
4
  import {
5
+ revokeToken
6
+ } from "./chunk-ESW573VH.js";
7
+ import {
8
+ clearAuth,
5
9
  loadAuth,
6
10
  loadProjectId,
7
11
  resolveHost,
8
12
  saveAuth,
9
13
  saveProjectLink
10
- } from "./chunk-B3HSTDGI.js";
14
+ } from "./chunk-EDGPZTOV.js";
11
15
  import {
12
16
  detectGitRemote,
13
17
  pickProjectIdForRepo,
@@ -182,6 +186,18 @@ Run: npx @insitue/claude-plugin link <projectId>
182
186
  }
183
187
  return 1;
184
188
  }
189
+ async function cmdLogout() {
190
+ const auth = loadAuth();
191
+ if (auth.token) {
192
+ try {
193
+ await revokeToken(resolveHost(auth), auth.token);
194
+ } catch {
195
+ }
196
+ }
197
+ clearAuth();
198
+ process.stdout.write("Signed out of InSitue.\n");
199
+ return 0;
200
+ }
185
201
  function cmdWhoami() {
186
202
  const auth = loadAuth();
187
203
  const projectDir = resolveProjectDir();
@@ -200,5 +216,6 @@ Project: ${projectId ?? "(not linked)"}
200
216
  export {
201
217
  cmdLink,
202
218
  cmdLogin,
219
+ cmdLogout,
203
220
  cmdWhoami
204
221
  };
package/dist/diagnose.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  diagnose
3
- } from "./chunk-KGRPDRYH.js";
4
- import "./chunk-B3HSTDGI.js";
3
+ } from "./chunk-ZLNSDVTY.js";
4
+ import "./chunk-EDGPZTOV.js";
5
5
  export {
6
6
  diagnose
7
7
  };
@@ -2,12 +2,12 @@
2
2
 
3
3
  // src/dispatcher.ts
4
4
  var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["setup", "diagnose", "help", "--help", "-h"]);
5
- var CLOUD_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "link", "whoami"]);
5
+ var CLOUD_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "link", "whoami", "logout"]);
6
6
  var first = process.argv[2];
7
7
  if (first && CLI_SUBCOMMANDS.has(first)) {
8
8
  await import("./setup-cli.js");
9
9
  } else if (first && CLOUD_SUBCOMMANDS.has(first)) {
10
- const { cmdLogin, cmdLink, cmdWhoami } = await import("./cloud-cli.js");
10
+ const { cmdLogin, cmdLink, cmdWhoami, cmdLogout } = await import("./cloud-cli.js");
11
11
  const rest = process.argv.slice(3);
12
12
  let code;
13
13
  switch (first) {
@@ -20,6 +20,9 @@ if (first && CLI_SUBCOMMANDS.has(first)) {
20
20
  case "whoami":
21
21
  code = cmdWhoami();
22
22
  break;
23
+ case "logout":
24
+ code = await cmdLogout();
25
+ break;
23
26
  default:
24
27
  code = 0;
25
28
  }
@@ -5,21 +5,23 @@ import {
5
5
  } from "./chunk-UNMH2DN4.js";
6
6
  import {
7
7
  diagnose
8
- } from "./chunk-KGRPDRYH.js";
8
+ } from "./chunk-ZLNSDVTY.js";
9
9
  import {
10
10
  CloudApiError,
11
11
  claimIssue,
12
12
  listIssues,
13
13
  releaseIssue,
14
- resolveIssue
15
- } from "./chunk-IRPBZWNQ.js";
14
+ resolveIssue,
15
+ revokeToken
16
+ } from "./chunk-ESW573VH.js";
16
17
  import {
18
+ clearAuth,
17
19
  loadAuth,
18
20
  loadProjectId,
19
21
  resolveHost,
20
22
  saveAuth,
21
23
  saveProjectLink
22
- } from "./chunk-B3HSTDGI.js";
24
+ } from "./chunk-EDGPZTOV.js";
23
25
  import {
24
26
  detectGitRemote,
25
27
  pickProjectIdForRepo,
@@ -928,6 +930,37 @@ server.registerTool(
928
930
  }
929
931
  }
930
932
  );
933
+ server.registerTool(
934
+ "logout",
935
+ {
936
+ description: "Sign out of InSitue Cloud: best-effort revoke this machine's token server-side, then clear local credentials. Logout always clears local creds even if the revoke call fails (network error, 4xx, etc.).",
937
+ inputSchema: {}
938
+ },
939
+ async () => {
940
+ const cfg = loadAuth();
941
+ let revoked = false;
942
+ if (cfg.token) {
943
+ try {
944
+ await revokeToken(resolveHost(cfg), cfg.token);
945
+ revoked = true;
946
+ } catch {
947
+ }
948
+ }
949
+ clearAuth();
950
+ return {
951
+ content: [
952
+ {
953
+ type: "text",
954
+ text: JSON.stringify({
955
+ status: "ok",
956
+ revoked,
957
+ message: "Signed out of InSitue."
958
+ })
959
+ }
960
+ ]
961
+ };
962
+ }
963
+ );
931
964
  function cloudSetup() {
932
965
  const auth = loadAuth();
933
966
  if (!auth.token) {
@@ -1162,6 +1195,30 @@ Show the user the returned URL and userCode, then call
1162
1195
  \`mcp__insitue__complete_authentication\` once they approve in the browser.
1163
1196
  Confirm the result with "Signed in as <login>" and linked project if any.`;
1164
1197
  }
1198
+ server.registerPrompt(
1199
+ "logout",
1200
+ {
1201
+ title: "Sign out of InSitue",
1202
+ description: "Sign out of InSitue Cloud \u2014 revokes this machine's token and clears local credentials."
1203
+ },
1204
+ () => ({
1205
+ messages: [
1206
+ {
1207
+ role: "user",
1208
+ content: {
1209
+ type: "text",
1210
+ text: readPkgFile("commands/logout.md") ?? logoutInstructions()
1211
+ }
1212
+ }
1213
+ ]
1214
+ })
1215
+ );
1216
+ function logoutInstructions() {
1217
+ return `# Sign out of InSitue
1218
+
1219
+ Call \`mcp__insitue__logout\` (no arguments).
1220
+ Confirm the result in one line, e.g. "Signed out of InSitue." or relay any error message.`;
1221
+ }
1165
1222
  function readPkgFile(rel) {
1166
1223
  const here = dirname3(fileURLToPath2(import.meta.url));
1167
1224
  for (const base of [join3(here, ".."), here]) {
package/dist/setup-cli.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-UNMH2DN4.js";
5
5
  import {
6
6
  diagnose
7
- } from "./chunk-KGRPDRYH.js";
8
- import "./chunk-B3HSTDGI.js";
7
+ } from "./chunk-ZLNSDVTY.js";
8
+ import "./chunk-EDGPZTOV.js";
9
9
 
10
10
  // src/setup-cli.ts
11
11
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insitue/claude-plugin",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Drive Claude (Code AND Desktop) from the InSitue browser overlay — pick an element in your app, claude reads the file and proposes the edit.",
5
5
  "keywords": [
6
6
  "insitue",