@insitue/claude-plugin 0.7.0 → 0.7.2

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.2",
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,14 @@
1
1
  # @insitue/claude-plugin
2
2
 
3
+ ## 0.7.2
4
+
5
+ - **Consistent slash commands.** Removed the duplicate MCP prompts for connect/login/logout, which Claude Code surfaced as differently-named `…insitue:<name> (MCP)` entries alongside the clean `/insitue:*` slash commands. Now there is one consistent surface: `/insitue:connect`, `/insitue:disconnect`, `/insitue:login`, `/insitue:logout` (from `commands/*.md`). On Claude Desktop, use the equivalent tools (`start_session`, `authenticate`+`complete_authentication`, `logout`).
6
+ - **Docs:** the channels (preview) section now documents the `allowedChannelPlugins` org-policy escape hatch to drop the `--dangerously-load-development-channels` flag.
7
+
8
+ ## 0.7.1
9
+
10
+ - **`/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`.
11
+
3
12
  ## 0.7.0
4
13
 
5
14
  - **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.
package/README.md CHANGED
@@ -201,6 +201,11 @@ channel listener falls back to the normal poll automatically.
201
201
  - This is a **Claude Code research-preview** feature. The flag
202
202
  `--dangerously-load-development-channels` is required during the
203
203
  preview period and may change or be renamed in a future release.
204
+ - **Dropping the flag:** on Team/Enterprise, an admin can add `insitue`
205
+ to the `allowedChannelPlugins` org policy — then the channel runs with
206
+ just `claude --channels plugin:insitue` (no dangerous flag). Once
207
+ channels leave research preview / the plugin is on Anthropic's default
208
+ allowlist, the flag won't be needed at all.
204
209
  - It works only with the CLI (`claude`), not Claude Desktop.
205
210
  - The standard `/insitue:connect` workflow (plain `claude`, no
206
211
  extra flags) continues to work exactly as before via polling —
@@ -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) {
@@ -1121,47 +1154,6 @@ server.registerTool(
1121
1154
  }
1122
1155
  }
1123
1156
  );
1124
- server.registerPrompt(
1125
- "connect",
1126
- {
1127
- title: "Connect to InSitue",
1128
- description: "Loads the operating instructions and begins the pick \u2192 edit loop."
1129
- },
1130
- () => ({
1131
- messages: [
1132
- {
1133
- role: "user",
1134
- content: { type: "text", text: loadInstructions() }
1135
- }
1136
- ]
1137
- })
1138
- );
1139
- server.registerPrompt(
1140
- "login",
1141
- {
1142
- title: "Sign in to InSitue",
1143
- description: "Browser-based sign-in to InSitue Cloud via PKCE. Opens your browser, confirms a pairing code, then saves credentials and auto-links the repo."
1144
- },
1145
- () => ({
1146
- messages: [
1147
- {
1148
- role: "user",
1149
- content: {
1150
- type: "text",
1151
- text: readPkgFile("commands/login.md") ?? loginInstructions()
1152
- }
1153
- }
1154
- ]
1155
- })
1156
- );
1157
- function loginInstructions() {
1158
- return `# Sign in to InSitue
1159
-
1160
- Call \`mcp__insitue__authenticate\` to start the browser sign-in flow.
1161
- Show the user the returned URL and userCode, then call
1162
- \`mcp__insitue__complete_authentication\` once they approve in the browser.
1163
- Confirm the result with "Signed in as <login>" and linked project if any.`;
1164
- }
1165
1157
  function readPkgFile(rel) {
1166
1158
  const here = dirname3(fileURLToPath2(import.meta.url));
1167
1159
  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.2",
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",