wirl 0.2.4 → 0.2.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.
Files changed (2) hide show
  1. package/bin.js +56 -7
  2. package/package.json +1 -1
package/bin.js CHANGED
@@ -4862,7 +4862,7 @@ var init_version = __esm({
4862
4862
  "packages/core/src/version.ts"() {
4863
4863
  "use strict";
4864
4864
  WORKSPACE_VERSION = "0.0.0";
4865
- BUILT_VERSION = true ? "0.2.4" : null;
4865
+ BUILT_VERSION = true ? "0.2.5" : null;
4866
4866
  }
4867
4867
  });
4868
4868
 
@@ -7530,7 +7530,8 @@ var SERVER_HEAD = String.raw`/**
7530
7530
  * and what you get. Under them, the app's pages on app.wirl.dev.
7531
7531
  *
7532
7532
  * The whole app is this one file:
7533
- * - The page is HTML this module returns: plain forms, no script.
7533
+ * - The page is HTML this module returns: plain forms, and one small script
7534
+ * for the Copy prompt buttons.
7534
7535
  * - Notes live in env.DB, a SQLite database that belongs to this app alone.
7535
7536
  * Its tables are in migrations/0001_init.sql, and wirl applies each new
7536
7537
  * file in migrations/ before a version goes live. Put the next change in
@@ -7695,17 +7696,30 @@ async function page(request, url, me, env) {
7695
7696
  "<style>" + STYLE + "</style>",
7696
7697
  "<main>",
7697
7698
  "<header><h1>" + TITLE + "</h1>",
7698
- "<p class='dim'>Your first app on wirl. Signed in as <b>" + escape(me.name) + "</b>" + (me.role ? " (" + escape(me.role) + ")" : "") + ".</p></header>",
7699
+ "<p class='dim'>Signed in as <b>" + escape(me.name) + "</b>" + (me.role ? " (" + escape(me.role) + ")" : "") + ".</p></header>",
7700
+ me.role === "owner" ? welcome() : "",
7699
7701
  shown,
7700
7702
  "<ul class='notes'>" + (notes.length === 0 ? "<li class='dim'>Nothing here yet.</li>" : notes.map((note) => card(note, me, archived)).join("")) + "</ul>",
7701
7703
  "<p class='dim'>Nightly tidy-up, which archives notes older than " + ARCHIVE_AFTER_DAYS + " days that nobody pinned: " +
7702
7704
  (lastRun ? "last run " + escape(lastRun.ran_at.slice(0, 16)) + " UTC: " + escape(lastRun.note) : "Not run yet.") + "</p>",
7703
7705
  prompts(request),
7704
7706
  "</main>",
7707
+ COPY_SCRIPT,
7705
7708
  "</html>",
7706
7709
  ].join("\n");
7707
7710
  }
7708
7711
 
7712
+ // For the app's owner only: what this is, in a box above the note form.
7713
+ function welcome() {
7714
+ return [
7715
+ "<section class='welcome'>",
7716
+ "<p class='kicker'>Your first app on wirl</p>",
7717
+ "<h2>Your coding agent just built this, and it's live.</h2>",
7718
+ "<p>A small team noticeboard: notes, a nightly tidy-up, company sign-in, its own database. It runs at this address, it's private to you until you share it, and it's yours to change. Try out the app below and then customize it.</p>",
7719
+ "</section>",
7720
+ ].join("");
7721
+ }
7722
+
7709
7723
  function form() {
7710
7724
  return [
7711
7725
  "<form class='add' method='post' action='/notes'>",
@@ -7776,12 +7790,16 @@ function prompts(request) {
7776
7790
  const step = (each) => {
7777
7791
  const stop = each.capability.indexOf(". ");
7778
7792
  return (
7779
- "<li class='step" + (each.optional ? " optional" : "") + "'>" +
7793
+ "<li class='step" + (each.number === 1 ? " first" : "") + (each.optional ? " optional" : "") + "'>" +
7780
7794
  "<h3><span class='number'>" + each.number + "</span> " + escape(each.title) +
7795
+ (each.number === 1 ? " <span class='badge start'>Start here</span>" : "") +
7781
7796
  (each.optional ? " <span class='badge'>Optional. The big one.</span>" : "") + "</h3>" +
7782
7797
  "<p class='dim'><b>" + escape(each.capability.slice(0, stop + 1)) + "</b> " + escape(each.capability.slice(stop + 2)) + "</p>" +
7783
- "<pre>" + escape(each.prompt) + "</pre>" +
7784
- "<p class='dim'>You get: " + escape(each.youGet) + "</p>" +
7798
+ "<div class='getrow'>" +
7799
+ "<button type='button' class='copy' data-copy-for='prompt-" + each.number + "'>Copy prompt</button>" +
7800
+ "<p class='dim'>You get: " + escape(each.youGet) + "</p></div>" +
7801
+ "<details class='prompt'><summary>Show the prompt</summary>" +
7802
+ "<pre id='prompt-" + each.number + "'>" + escape(each.prompt) + "</pre></details>" +
7785
7803
  "</li>"
7786
7804
  );
7787
7805
  };
@@ -7809,6 +7827,7 @@ const STYLE = [
7809
7827
  "a { color: var(--accent); } .dim { color: var(--dim); }",
7810
7828
  "form.add, form.edit { display: grid; gap: 8px; margin: 16px 0 8px; }",
7811
7829
  "textarea, input, button { font: inherit; color: inherit; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); }",
7830
+ "button.copy { min-height: 44px; margin-top: 4px; }",
7812
7831
  "button { cursor: pointer; } button.primary { justify-self: start; background: var(--accent); border-color: var(--accent); color: var(--bg); }",
7813
7832
  "ul.notes { list-style: none; padding: 0; display: grid; gap: 10px; }",
7814
7833
  ".note { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; }",
@@ -7825,11 +7844,41 @@ const STYLE = [
7825
7844
  ".number { font-size: 12px; background: var(--ink); color: var(--bg); padding: 2px 7px; border-radius: 5px; }",
7826
7845
  ".optional .number { background: var(--accent); }",
7827
7846
  ".badge { font-size: 12px; font-weight: 600; color: var(--dim); border: 1px solid var(--line); padding: 1px 8px; border-radius: 999px; }",
7847
+ ".step.first { border: 2px solid var(--accent); }",
7848
+ ".badge.start { color: var(--accent); border-color: var(--accent); }",
7849
+ ".welcome { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; margin: 16px 0 8px; }",
7850
+ ".welcome h2 { font-size: 19px; margin: 4px 0 8px; } .welcome p { margin: 0; }",
7851
+ ".welcome .kicker { font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }",
7852
+ ".getrow { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; } .getrow p { margin: 0; }",
7853
+ "details.prompt summary { display: flex; align-items: center; min-height: 44px; color: var(--dim); font-size: 14px; cursor: pointer; }",
7828
7854
  ".uses { border-top: 1px solid var(--line); padding-top: 12px; font-size: 14px; }",
7829
7855
  "pre { white-space: pre-wrap; user-select: all; background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 10px; font-size: 13px; }",
7830
7856
  "details { margin: 6px 0; } summary { cursor: pointer; }",
7831
7857
  ].join("\n");
7832
7858
 
7859
+ const COPY_SCRIPT = [
7860
+ "<script>",
7861
+ "document.addEventListener('click', (event) => {",
7862
+ " const button = event.target.closest('.copy');",
7863
+ " if (!button) return;",
7864
+ " const pre = document.getElementById(button.getAttribute('data-copy-for'));",
7865
+ " const flash = (label) => {",
7866
+ " button.textContent = label;",
7867
+ " setTimeout(() => { button.textContent = 'Copy prompt'; }, 1500);",
7868
+ " };",
7869
+ " const select = () => {",
7870
+ " const range = document.createRange();",
7871
+ " range.selectNodeContents(pre);",
7872
+ " window.getSelection().removeAllRanges();",
7873
+ " window.getSelection().addRange(range);",
7874
+ " flash('Select and copy');",
7875
+ " };",
7876
+ " if (!navigator.clipboard) return select();",
7877
+ " navigator.clipboard.writeText(pre.textContent).then(() => flash('Copied'), select);",
7878
+ "});",
7879
+ "</script>",
7880
+ ].join("\n");
7881
+
7833
7882
  const home = (to = "/") => new Response(null, { status: 303, headers: { location: to } });
7834
7883
 
7835
7884
  const text = (body, status = 200) => new Response(body, { status, headers: { "content-type": "text/plain; charset=utf-8" } });
@@ -7867,7 +7916,7 @@ var STARTER_MIGRATION = [
7867
7916
  "-- Make the next change in 0002_<what>.sql; never edit a file that has been deployed.",
7868
7917
  "create table notes (id integer primary key, body text not null, tags text not null default '', pinned integer not null default 0, author_id text not null, author_name text not null default '', created_at text not null default (datetime('now')), archived_at text)",
7869
7918
  "create table runs (id integer primary key, schedule text not null, note text not null, ran_at text not null default (datetime('now')))",
7870
- "insert into notes (body, tags, pinned, author_id, author_name) values ('Welcome to the noticeboard. Post a note below, tag it, and pin the ones everyone should see.', 'welcome', 1, '', 'wirl')",
7919
+ "insert into notes (body, tags, pinned, author_id, author_name) values ('Welcome to the noticeboard. This note is pinned so everyone sees it first; post your own below.', 'welcome', 1, '', 'wirl')",
7871
7920
  ""
7872
7921
  ].join("\n");
7873
7922
  function starterManifest(app, org) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wirl",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Deploy an internal app somewhere real, privately. One command; sharing by email; API keys declared, never pasted.",
5
5
  "keywords": [
6
6
  "deploy",