@sparelabs/sightline-extension-cli 0.1.5 → 0.1.6

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 CHANGED
@@ -18,8 +18,8 @@ You need Node 20.19+, [Deno](https://deno.com) (the extension runtime) and Docke
18
18
  | `build` | Validates `sightline.extension.json` against the published contract (`@sparelabs/sightline-extension-manifest`) and the rules Sightline applies at publish (trust `T2`, a hosted runtime, a kebab-case id, `MAJOR.MINOR.PATCH`), checks `migrations/NNNN_<name>.sql` (numbered from `0001`, no gaps, at most 256 KB each), bundles `server/main.ts` into one ESM file (`runtime.entry`, usually `dist/server.mjs`, at most 5 MB) and lints the bundle with the same `lintBundle` Sightline runs at publish (from `@sparelabs/sightline-extension-manifest`: no remote, package or relative imports, no computed dynamic import). With `ui.frames` in the manifest it also reads your UI build from `dist/ui` (set `"ui": { "dir": … }` in `sightline-ext.json` to move it; build the UI with your own tool first) and checks it with Sightline's publish rules: allowed file types, sizes, no scripts from other origins, no root-absolute URLs (use a relative base, e.g. Vite `base: './'`), the entry HTML present. |
19
19
  | `dev [--port <n>] [--core-port 8787] [--no-db]` | Builds, starts the emulated core (`@sparelabs/sightline-extension-devkit`), your Postgres with your migrations, and the bundle under the **same Deno permission flags as production**; rebuilds and restarts on every change. `npx sightline-devkit invoke tool <name> --as user:alice` calls it. |
20
20
  | `test [--no-build] [--no-db] [--keep-db]` | Builds, runs the extension against the emulator and its own database, and checks it against the HTTP contract (`@sparelabs/sightline-extension-testing`): health, token refusal, the `ToolResult` envelope, routing. Exit 1 on any failure. |
21
- | `deploy [--bindings bindings.json] [--no-build]` | Builds, publishes the release to a workspace (identical bytes are a no-op) and installs it. Refuses when another version is installed: use `upgrade`. |
22
- | `upgrade [--bindings bindings.json] [--no-build]` | Builds, publishes, and moves the installed extension to the manifest's version. A permission the new version adds needs a binding. |
21
+ | `deploy [--no-build]` | Builds, publishes the release to a workspace (identical bytes are a no-op) and installs it. Refuses when another version is installed: use `upgrade`. |
22
+ | `upgrade [--no-build]` | Builds, publishes, and moves the installed extension to the manifest's version. A default access line the new version adds needs an Administrator's approval first. |
23
23
  | `uninstall [<id>] [--purge --yes]` | Uninstalls. Data is kept 30 days; `--purge --yes` drops it now. |
24
24
  | `yank <version> [--reason "…"] [--id <ext>]` | Withdraws a published release: it can no longer be installed, upgraded or rolled back to. An installation running it keeps running, flagged (the CLI warns) until you upgrade it. Idempotent; there is no un-yank. A deploy token needs the `yank` action. |
25
25
  | `run <job> [--no-wait] [--timeout <s>] [--id <ext>]` | Starts a run of the job now, outside its schedule, then reads its status every 2 s until it finishes (a job that continues makes several calls under one run), printing each call (trigger, status, HTTP status, duration, error) and the result. Exit 1 unless it `succeeded`. `--no-wait` returns once it started; past `--timeout` (default 900 s) the CLI stops waiting, the run goes on. A deploy token needs the `run_job` action. |
@@ -71,7 +71,7 @@ The emulator also gets the manifest, so its webhooks are verified like Sightline
71
71
  ```bash
72
72
  export SIGHTLINE_URL=https://<your workspace>
73
73
  export SIGHTLINE_DEPLOY_TOKEN=… # issued by a workspace admin; only ever read from the environment
74
- npx sightline-ext deploy --bindings bindings.json
74
+ npx sightline-ext deploy
75
75
  ```
76
76
 
77
77
  | Variable | Meaning |
@@ -81,7 +81,7 @@ npx sightline-ext deploy --bindings bindings.json
81
81
  | `SIGHTLINE_DEPLOY_TOKEN` | A deploy token (`slxd_…`) a workspace admin issued for your extension ids and actions, or an admin's own session token. A deploy token goes to the workspace's deploy routes (`/functions/v1/core/v1/deploy/…`), the only place it works. It is sent to that workspace only, never accepted as a flag, never in the URL. |
82
82
  | `SIGHTLINE_API_KEY` | The gateway's public API key, when the workspace needs one (sent as `apikey`). |
83
83
 
84
- `bindings.json` maps each permission your manifest declares to a Sightline permission the deploying admin holds: `{ "my-notes.read": "employees", "my-notes.write": "employees" }`. A permission left out gets the manifest's proposed `default` when the admin holds it.
84
+ Access control is the manifest's `rbac`: its resources, the permissions your tools name, and default access lines (`grants`). A deploy token never approves access: when the release has default access lines nobody decided yet, `deploy` and `upgrade` stop with `consent_required` and list them; an Administrator approves or declines them in Setup → Extensions (or installs from there), then run it again. `--bindings` (permission bindings) was removed in 0.1.6 and is refused.
85
85
 
86
86
  The deploy publishes the server bundle and migrations. Publishing a UI (`ui.frames`) to the workspace's extension-UI host is not part of the release API yet.
87
87
 
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const USAGE = "sightline-ext <command> [options]\n\n init <dir> Scaffold a new extension repository\n [--id <kebab-id>] [--name \"Display name\"] [--publisher <kebab-id>] [--force]\n build Validate the manifest and migrations, bundle server/main.ts into dist/server.mjs\n dev Build, then run the extension against an emulated Sightline, rebuilding on change\n [--port <n>] [--core-port 8787] [--no-db]\n test Build, run the extension against the emulator, and check the HTTP contract\n [--no-build] [--no-db] [--keep-db]\n deploy Build, publish the release and install it in a workspace\n upgrade Build, publish the release and move the installed extension to it\n (deploy, upgrade: [--bindings bindings.json] [--no-build])\n uninstall Remove the extension from the workspace (its data is kept 30 days)\n [--purge --yes]\n yank <version> Withdraw a published release: it can no longer be installed, upgraded or rolled\n back to (an installation running it keeps running, flagged). No un-yank.\n [--reason \"\u2026\"]\n run <job> Start a run of a job now, outside its schedule, wait for it and print each call\n and the result; exit 1 unless it succeeded. [--no-wait] [--timeout <seconds, default 900>]\n webhooks send <name> --body <file>\n Sign the file's raw bytes the way Sightline verifies them and POST them: to the\n running `dev` (verified and forwarded to your /hooks/<name>), or with\n --url <webhook URL from Setup> to a workspace. The secret is read from\n SL_SECRET_<NAME> (or --secret-env VAR, or devSecrets), never from a flag.\n [--url <url>] [--secret-env VAR] [--content-type application/json] [--timestamp <unix s>]\n\n Common: [--dir <project>] [--manifest sightline.extension.json] [--config sightline-ext.json]\n deploy, upgrade, uninstall, yank, run: [--url https://<workspace>] [--api-url <core API base>]\n yank, run: on the project's extension (the manifest's id), or --id <extension id> with no project.\n A deploy token needs the action: publish, install, upgrade, uninstall, yank or run_job.\n\nDeploying needs the workspace and a deploy token issued by one of its admins:\n SIGHTLINE_URL https://<your workspace> (or SIGHTLINE_API_URL, the full core API base)\n SIGHTLINE_DEPLOY_TOKEN the token (only ever read from the environment)\n SIGHTLINE_API_KEY the gateway's public api key, when your workspace needs one";
1
+ export declare const USAGE = "sightline-ext <command> [options]\n\n init <dir> Scaffold a new extension repository\n [--id <kebab-id>] [--name \"Display name\"] [--publisher <kebab-id>] [--force]\n build Validate the manifest and migrations, bundle server/main.ts into dist/server.mjs\n dev Build, then run the extension against an emulated Sightline, rebuilding on change\n [--port <n>] [--core-port 8787] [--no-db]\n test Build, run the extension against the emulator, and check the HTTP contract\n [--no-build] [--no-db] [--keep-db]\n deploy Build, publish the release and install it in a workspace\n upgrade Build, publish the release and move the installed extension to it\n (deploy, upgrade: [--no-build]; new default access waits for an admin's approval)\n uninstall Remove the extension from the workspace (its data is kept 30 days)\n [--purge --yes]\n yank <version> Withdraw a published release: it can no longer be installed, upgraded or rolled\n back to (an installation running it keeps running, flagged). No un-yank.\n [--reason \"\u2026\"]\n run <job> Start a run of a job now, outside its schedule, wait for it and print each call\n and the result; exit 1 unless it succeeded. [--no-wait] [--timeout <seconds, default 900>]\n webhooks send <name> --body <file>\n Sign the file's raw bytes the way Sightline verifies them and POST them: to the\n running `dev` (verified and forwarded to your /hooks/<name>), or with\n --url <webhook URL from Setup> to a workspace. The secret is read from\n SL_SECRET_<NAME> (or --secret-env VAR, or devSecrets), never from a flag.\n [--url <url>] [--secret-env VAR] [--content-type application/json] [--timestamp <unix s>]\n\n Common: [--dir <project>] [--manifest sightline.extension.json] [--config sightline-ext.json]\n deploy, upgrade, uninstall, yank, run: [--url https://<workspace>] [--api-url <core API base>]\n yank, run: on the project's extension (the manifest's id), or --id <extension id> with no project.\n A deploy token needs the action: publish, install, upgrade, uninstall, yank or run_job.\n\nDeploying needs the workspace and a deploy token issued by one of its admins:\n SIGHTLINE_URL https://<your workspace> (or SIGHTLINE_API_URL, the full core API base)\n SIGHTLINE_DEPLOY_TOKEN the token (only ever read from the environment)\n SIGHTLINE_API_KEY the gateway's public api key, when your workspace needs one";
2
2
  export type Out = (line: string) => void;
3
3
  export declare function packageVersion(): string;
4
4
  export declare function main(argv: string[], out?: Out): Promise<number>;
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import { assertContract, formatReport, runContractTests } from "@sparelabs/sight
8
8
  import { bool, int, parseArgs, str } from "./args.js";
9
9
  import { build, bundleOptions } from "./build.js";
10
10
  import { CoreApiError, createCoreApi, describeError } from "./core-api.js";
11
- import { deploy, parseBindings, runJob, uninstall, upgrade, yank } from "./deploy.js";
11
+ import { deploy, runJob, uninstall, upgrade, yank } from "./deploy.js";
12
12
  import { contractConfig, emulatorConfig, secretEnv } from "./local-run.js";
13
13
  import { loadProject } from "./project.js";
14
14
  import { templateFiles } from "./template.js";
@@ -24,7 +24,7 @@ export const USAGE = `sightline-ext <command> [options]
24
24
  [--no-build] [--no-db] [--keep-db]
25
25
  deploy Build, publish the release and install it in a workspace
26
26
  upgrade Build, publish the release and move the installed extension to it
27
- (deploy, upgrade: [--bindings bindings.json] [--no-build])
27
+ (deploy, upgrade: [--no-build]; new default access waits for an admin's approval)
28
28
  uninstall Remove the extension from the workspace (its data is kept 30 days)
29
29
  [--purge --yes]
30
30
  yank <version> Withdraw a published release: it can no longer be installed, upgraded or rolled
@@ -253,11 +253,11 @@ function extensionId(flags) {
253
253
  throw new Error("name the extension: --id <extension id>, or run in its project (the manifest's id)");
254
254
  return id;
255
255
  }
256
- function readBindings(flags) {
257
- const file = str(flags, "bindings");
258
- if (!file)
259
- return undefined;
260
- return parseBindings(JSON.parse(readFileSync(file, "utf8")));
256
+ /** `--bindings` was removed with permission bindings: say so instead of silently ignoring it. */
257
+ function refuseBindingsFlag(flags) {
258
+ if (flags.bindings !== undefined) {
259
+ throw new Error("--bindings was removed: declare `rbac` in the manifest; an Administrator approves its default access in Setup → Extensions");
260
+ }
261
261
  }
262
262
  async function release(flags, out) {
263
263
  const p = project(flags);
@@ -291,13 +291,15 @@ export async function main(argv, out = console.log) {
291
291
  case "test":
292
292
  return await test(flags, out);
293
293
  case "deploy": {
294
+ refuseBindingsFlag(flags);
294
295
  const api = coreApiFromEnv(flags);
295
- await deploy(api, await release(flags, out), { bindings: readBindings(flags) }, out);
296
+ await deploy(api, await release(flags, out), out);
296
297
  return 0;
297
298
  }
298
299
  case "upgrade": {
300
+ refuseBindingsFlag(flags);
299
301
  const api = coreApiFromEnv(flags);
300
- await upgrade(api, await release(flags, out), { bindings: readBindings(flags) }, out);
302
+ await upgrade(api, await release(flags, out), out);
301
303
  return 0;
302
304
  }
303
305
  case "uninstall": {
@@ -35,7 +35,6 @@ export interface InstallationView {
35
35
  installationId: string;
36
36
  state: string;
37
37
  version: string;
38
- bindings?: Record<string, string>;
39
38
  lastError?: string | null;
40
39
  [key: string]: unknown;
41
40
  }
@@ -104,11 +103,9 @@ export interface CoreApi {
104
103
  }>;
105
104
  install(id: string, body: {
106
105
  version: string;
107
- bindings?: Record<string, string>;
108
106
  }): Promise<InstallationView>;
109
107
  upgrade(id: string, body: {
110
108
  version: string;
111
- bindings?: Record<string, string>;
112
109
  }): Promise<InstallationView>;
113
110
  uninstall(id: string, body: {
114
111
  purge?: boolean;
package/dist/core-api.js CHANGED
@@ -3,8 +3,8 @@
3
3
  //
4
4
  // GET /core/v1/extensions { installations, releases }
5
5
  // POST /core/v1/extensions/releases { manifest, bundle: { base64, sha256 }, migrations? }
6
- // POST /core/v1/extensions/:id/install { version, bindings? }
7
- // POST /core/v1/extensions/:id/upgrade { version, bindings? }
6
+ // POST /core/v1/extensions/:id/install { version }
7
+ // POST /core/v1/extensions/:id/upgrade { version }
8
8
  // POST /core/v1/extensions/:id/uninstall { purge? }
9
9
  // POST /core/v1/extensions/:id/releases/:version/yank { reason? } → { release, installed }
10
10
  // POST /core/v1/extensions/:id/jobs/:name/run 202 { run }
@@ -62,11 +62,9 @@ export function describeError(err) {
62
62
  switch (err.code) {
63
63
  case "route_missing":
64
64
  return err.message;
65
- case "consent_required":
66
- case "binding_required": {
67
- const missing = (d.missing ?? d.permissions ?? []);
68
- const names = missing.map((p) => (typeof p === "string" ? p : `${p.permission ?? p.key}${p.proposed ? ` (proposed: ${p.proposed})` : ""}`));
69
- return `${err.message}${names.length ? `\n bind: ${names.join(", ")}` : ""}\n pass --bindings bindings.json ({ "<permission>": "<core permission you hold>" })`;
65
+ case "consent_required": {
66
+ const pending = (d.ledger?.pending ?? []).map((l) => l.id).filter(Boolean);
67
+ return `${err.message}${pending.length ? `\n pending: ${pending.join(", ")}` : ""}\n an Administrator approves it in Setup → Extensions, then run this again`;
70
68
  }
71
69
  case "invalid_manifest": {
72
70
  const errors = (d.errors ?? []);
package/dist/deploy.d.ts CHANGED
@@ -1,16 +1,10 @@
1
1
  import { type CoreApi, type InstallationView, type JobRunView, type PublishInput, type ReleaseView } from "./core-api.ts";
2
2
  export type Out = (line: string) => void;
3
- export declare function deploy(api: CoreApi, release: PublishInput, options: {
4
- bindings?: Record<string, string>;
5
- }, out: Out): Promise<InstallationView>;
6
- export declare function upgrade(api: CoreApi, release: PublishInput, options: {
7
- bindings?: Record<string, string>;
8
- }, out: Out): Promise<InstallationView>;
3
+ export declare function deploy(api: CoreApi, release: PublishInput, out: Out): Promise<InstallationView>;
4
+ export declare function upgrade(api: CoreApi, release: PublishInput, out: Out): Promise<InstallationView>;
9
5
  export declare function uninstall(api: CoreApi, id: string, options: {
10
6
  purge: boolean;
11
7
  }, out: Out): Promise<InstallationView>;
12
- /** --bindings <file>: { "<ext>.<permission>": "<core permission>" }. */
13
- export declare function parseBindings(raw: unknown): Record<string, string>;
14
8
  /** Core's cap on a yank reason. */
15
9
  export declare const MAX_YANK_REASON = 500;
16
10
  /**
package/dist/deploy.js CHANGED
@@ -23,7 +23,7 @@ async function publish(api, release, out) {
23
23
  if (published.coreApiCompatible === false)
24
24
  out(` warning: this workspace's core does not satisfy coreApi ${String(release.manifest.coreApi)}; install will be refused`);
25
25
  }
26
- export async function deploy(api, release, options, out) {
26
+ export async function deploy(api, release, out) {
27
27
  const id = release.manifest.id;
28
28
  const version = release.manifest.version;
29
29
  const existing = await current(api, id);
@@ -35,11 +35,11 @@ export async function deploy(api, release, options, out) {
35
35
  out(`${id}@${version} is already installed (${existing.state}); nothing to do`);
36
36
  return existing;
37
37
  }
38
- const installation = await api.install(id, { version, ...(options.bindings ? { bindings: options.bindings } : {}) });
38
+ const installation = await api.install(id, { version });
39
39
  out(`installed ${id}@${installation.version}: ${installation.state} (installation ${installation.installationId})`);
40
40
  return installation;
41
41
  }
42
- export async function upgrade(api, release, options, out) {
42
+ export async function upgrade(api, release, out) {
43
43
  const id = release.manifest.id;
44
44
  const version = release.manifest.version;
45
45
  const existing = await current(api, id);
@@ -50,7 +50,7 @@ export async function upgrade(api, release, options, out) {
50
50
  out(`${id} already runs ${version}; nothing to upgrade (bump "version" in the manifest to release a change)`);
51
51
  return existing;
52
52
  }
53
- const installation = await api.upgrade(id, { version, ...(options.bindings ? { bindings: options.bindings } : {}) });
53
+ const installation = await api.upgrade(id, { version });
54
54
  out(`upgraded ${id} ${existing.version} → ${installation.version}: ${installation.state}`);
55
55
  return installation;
56
56
  }
@@ -63,18 +63,6 @@ export async function uninstall(api, id, options, out) {
63
63
  out(` warning: ${w}`);
64
64
  return installation;
65
65
  }
66
- /** --bindings <file>: { "<ext>.<permission>": "<core permission>" }. */
67
- export function parseBindings(raw) {
68
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
69
- throw new Error("bindings must be a JSON object of permission → core permission");
70
- const out = {};
71
- for (const [k, v] of Object.entries(raw)) {
72
- if (typeof v !== "string" || v === "")
73
- throw new Error(`the binding for ${k} must be a core permission name`);
74
- out[k] = v;
75
- }
76
- return out;
77
- }
78
66
  const RELEASE_VERSION_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
79
67
  /** Core's cap on a yank reason. */
80
68
  export const MAX_YANK_REASON = 500;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { main, packageVersion, USAGE } from "./cli.ts";
2
2
  export { bool, type Flags, parseArgs, type ParsedArgs, str } from "./args.ts";
3
3
  export { build, type BuildDeps, type BuildResult, type Bundler, type BundleLinter, bundleOptions, type BundleOptions, collectUi, manifestProblems, type ManifestValidator, type UiValidator } from "./build.ts";
4
4
  export { apiBase, type CoreApi, CoreApiError, type CoreApiOptions, createCoreApi, describeError, type InstallationView, isDeployToken, type JobCallView, type JobRunView, lifecycleBase, type PublishInput, type ReleaseView, sha256Hex } from "./core-api.ts";
5
- export { deploy, MAX_YANK_REASON, parseBindings, runJob, type RunJobOptions, uninstall, upgrade, yank } from "./deploy.ts";
5
+ export { deploy, MAX_YANK_REASON, runJob, type RunJobOptions, uninstall, upgrade, yank } from "./deploy.ts";
6
6
  export { contractConfig, type ContractRunConfig, type EmulatorConfig, emulatorConfig, secretEnv } from "./local-run.ts";
7
7
  export { CONFIG_FILE, type ContractConfig, defaultContract, hostedRuleProblems, loadProject, MANIFEST_FILE, migrationProblems, type MigrationFile, type PermissionCheckConfig, type PersonConfig, type Project, type ProjectConfig, readMigrations, readUiFiles, type UiFileOnDisk, uiFrames, type UserConfig, type WorkspaceConfig, } from "./project.ts";
8
8
  export { lintBundle, MAX_BUNDLE_BYTES } from "@sparelabs/sightline-extension-manifest";
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export { main, packageVersion, USAGE } from "./cli.js";
5
5
  export { bool, parseArgs, str } from "./args.js";
6
6
  export { build, bundleOptions, collectUi, manifestProblems } from "./build.js";
7
7
  export { apiBase, CoreApiError, createCoreApi, describeError, isDeployToken, lifecycleBase, sha256Hex } from "./core-api.js";
8
- export { deploy, MAX_YANK_REASON, parseBindings, runJob, uninstall, upgrade, yank } from "./deploy.js";
8
+ export { deploy, MAX_YANK_REASON, runJob, uninstall, upgrade, yank } from "./deploy.js";
9
9
  export { contractConfig, emulatorConfig, secretEnv } from "./local-run.js";
10
10
  export { CONFIG_FILE, defaultContract, hostedRuleProblems, loadProject, MANIFEST_FILE, migrationProblems, readMigrations, readUiFiles, uiFrames, } from "./project.js";
11
11
  // The bundle lint is the published contract's, the same function core's installer runs.
package/dist/template.js CHANGED
@@ -34,10 +34,16 @@ export function templateFiles(options) {
34
34
  trust: "T2",
35
35
  coreApi: "^0.1",
36
36
  runtime: { kind: "hosted", entry: "dist/server.mjs", memoryMb: 256 },
37
- permissions: [
38
- { key: `${id}.read`, label: "Read notes", default: "employees" },
39
- { key: `${id}.write`, label: "Write notes", default: "employees" },
40
- ],
37
+ // Access control: one resource, the permissions the tools name, and the
38
+ // default access a workspace admin approves on install (Setup → Extensions).
39
+ rbac: {
40
+ resources: [{ key: `${id}.notes`, label: "Notes", description: "Notes your team keeps.", read: ["self", "reports", "others"], write: ["self"] }],
41
+ permissions: [
42
+ { key: `${id}.read`, label: "Read notes", requires: [`${id}.notes`] },
43
+ { key: `${id}.write`, label: "Write notes", requires: [`${id}.notes`], requireWrite: true },
44
+ ],
45
+ grants: [{ role: "employee", resource: `${id}.notes`, read: ["others"], write: ["self"] }],
46
+ },
41
47
  tools: [
42
48
  {
43
49
  name: `${p}_list`,
@@ -203,7 +209,7 @@ SIGHTLINE_URL=https://<your workspace> SIGHTLINE_DEPLOY_TOKEN=… npx sightline-
203
209
 
204
210
  | Path | What |
205
211
  | --- | --- |
206
- | \`sightline.extension.json\` | The manifest: id, version, permissions, tools |
212
+ | \`sightline.extension.json\` | The manifest: id, version, access control (\`rbac\`), tools |
207
213
  | \`server/main.ts\` | The backend (\`@sparelabs/sightline-extension-sdk\`) |
208
214
  | \`migrations/NNNN_<name>.sql\` | Your database, in order; only ever add files |
209
215
  | \`sightline-ext.json\` | Local only: what \`test\` calls, dev settings and secrets |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparelabs/sightline-extension-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "sightline-ext: scaffold, run, build, test and deploy a hosted Sightline extension.",
5
5
  "license": "MIT",
6
6
  "author": "Spare Labs Inc.",
@@ -34,9 +34,9 @@
34
34
  "typecheck": "tsc -p tsconfig.json"
35
35
  },
36
36
  "dependencies": {
37
- "@sparelabs/sightline-extension-devkit": "0.1.4",
38
- "@sparelabs/sightline-extension-manifest": "0.1.2",
39
- "@sparelabs/sightline-extension-testing": "0.1.0",
37
+ "@sparelabs/sightline-extension-devkit": "0.1.5",
38
+ "@sparelabs/sightline-extension-manifest": "0.1.3",
39
+ "@sparelabs/sightline-extension-testing": "0.1.1",
40
40
  "esbuild": "^0.25.10"
41
41
  },
42
42
  "devDependencies": {