@design-twin/dtwin 0.1.4 → 0.1.5

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.
@@ -4069,7 +4069,7 @@
4069
4069
  // freshly reloaded one, since neither startedAt nor code.js's mtime can. Reused verbatim by
4070
4070
  // the `hello` announcement below (main.ts's get-identity -> ui.html -> bridge), so `whoami`,
4071
4071
  // `dtwin list clients` and `dtwin doctor` can never disagree about which build is running.
4072
- pluginVersion: "0.1.4",
4072
+ pluginVersion: "0.1.5",
4073
4073
  fileKey: fileKey === void 0 ? null : fileKey,
4074
4074
  fileKeyAvailable: typeof fileKey === "string" && fileKey.length > 0,
4075
4075
  // So figma_write's dry run can say a real write would be refused before anyone sends one.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@design-twin/dtwin",
3
- "version": "0.1.4",
4
- "description": "Figma → code with Claude Code: the dtwin CLI + MCP server (and the Figma plugin) that read a design on the free Figma plan into your project, fully offline.",
3
+ "version": "0.1.5",
4
+ "description": "Figma → code with Claude Code: the dtwin CLI + MCP server (and the Figma plugin) that read a design on the free Figma plan into your project. No REST API key, no cloud service in between.",
5
5
  "license": "MIT",
6
6
  "author": "Mohamed Magdy Omar",
7
7
  "repository": {
package/src/figma-pull.ts CHANGED
@@ -894,7 +894,9 @@ async function openSession(parsed: ParsedArgs, settings: BridgeSettings): Promis
894
894
  // one gets more time once a plugin is connected, and with no target or a file name the fresh bridge
895
895
  // settles first (timeouts.ts SETTLE_MS), so a second open file a redial behind is connected — and the
896
896
  // command refused as ambiguous, or listed — instead of the first file to land being taken silently.
897
- timing.connectMs = (await route.connect(client)).waitedMs;
897
+ // No plugin in the whole window fails here (route.ts), so no command prints "plugin connected — …" first; the
898
+ // clients listing alone answers "none".
899
+ timing.connectMs = (await route.connect(client, { listing: command.id === "listClients" })).waitedMs;
898
900
  // Where the time went, for the closing `done in …` line. The connect wait is measured above
899
901
  // (own bridge only — a daemon does its waiting inside the request), the export is the time inside
900
902
  // every request, the write is every write-out (read-run.ts adds both to `timing`). All measured from
package/src/route.ts CHANGED
@@ -169,8 +169,10 @@ export interface RouteRequest {
169
169
  export interface Route {
170
170
  /** Spend the connect window (a one-shot route over its own bridge; otherwise nothing to wait for here) —
171
171
  * once: later calls answer the first one's result. Requests and listClients call it themselves; a caller
172
- * calls it first only to time the wait. `target` is what that first wait waits for. */
173
- connect(target?: string | null): Promise<{ waitedMs: number }>;
172
+ * calls it first only to time the wait. `target` is what that first wait waits for. A window in which no plugin
173
+ * ever connected throws the never-connected text here, before the caller says what it is about to do — unless
174
+ * `listing` (the clients listing, whose answer is then "none"). */
175
+ connect(target?: string | null, o?: { listing?: boolean }): Promise<{ waitedMs: number }>;
174
176
  request<C extends Cmd>(cmd: C, args: Commands[C]["args"], o?: RouteRequest): Promise<Sent<C>>;
175
177
  listClients(): Promise<ClientRow[]>;
176
178
  /** The socket half of whoami for `connId` (the connection a request was answered by), and who holds it. */
@@ -206,8 +208,9 @@ export function createRoute(upstream: () => Promise<Upstream>, policy: RoutePoli
206
208
  }
207
209
 
208
210
  return {
209
- async connect(target) {
210
- const { waitedMs } = await spend(await upstream(), target);
211
+ async connect(target, { listing = false } = {}) {
212
+ const { waitedMs, everConnected } = await spend(await upstream(), target);
213
+ if (everConnected === false && !listing) throw neverConnected(policy.connectWaitMs);
211
214
  return { waitedMs };
212
215
  },
213
216
  async request(cmd, args, o = {}) {