flostep 0.1.2 → 0.1.4

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/AGENTS.md CHANGED
@@ -35,7 +35,7 @@ Customer -> API: POST /checkout
35
35
  API -> Payments: charge card
36
36
  API -> Customer: order confirmed
37
37
  EOF
38
- # ✓ Created #42 Checkout
38
+ # ✓ Created #Xk3p9QvA2wE Checkout
39
39
  # https://flostep.dev/s/rEFdW8GSDwQ <- give the user this
40
40
  ```
41
41
 
@@ -44,36 +44,36 @@ EOF
44
44
  For a diagram that already exists, share it on its own:
45
45
 
46
46
  ```bash
47
- npx flostep share 42 # prints the public link
48
- npx flostep share 42 --embed # iframe URL, for a docs page
47
+ npx flostep share Xk3p9QvA2wE # prints the public link
48
+ npx flostep share Xk3p9QvA2wE --embed # iframe URL, for a docs page
49
49
  ```
50
50
 
51
51
  GitHub strips iframes, so for a README, an ADR or a PR description print a markdown image that links to the diagram instead (paid plans; on a free one the command fails and gives you the plain link):
52
52
 
53
53
  ```bash
54
- npx flostep share 42 --markdown # an image that follows the diagram as it changes
54
+ npx flostep share Xk3p9QvA2wE --markdown # an image that follows the diagram as it changes
55
55
  ```
56
56
 
57
57
  If the user keeps the steps in a file in their repo, pipe the file in and let them keep the file — the CLI tracks nothing on disk:
58
58
 
59
59
  ```bash
60
- npx flostep update 42 < docs/checkout.flostep
60
+ npx flostep update Xk3p9QvA2wE < docs/checkout.flostep
61
61
  ```
62
62
 
63
63
  To rewrite an existing diagram, read it, transform it, pipe it back:
64
64
 
65
65
  ```bash
66
- npx flostep show 42 | sed 's/Redis/Session Cache/' | npx flostep update 42
66
+ npx flostep show Xk3p9QvA2wE | sed 's/Redis/Session Cache/' | npx flostep update Xk3p9QvA2wE
67
67
  ```
68
68
 
69
69
  Or change one step at a time when you have no local file:
70
70
 
71
71
  ```bash
72
- npx flostep show 42 # read it first
73
- npx flostep step add 42 "API -> Cache: read session"
74
- npx flostep step add 42 "Client -> API: retry" --at 3
75
- npx flostep step rm 42 5
76
- npx flostep node rename 42 "Redis" "Session Cache"
72
+ npx flostep show Xk3p9QvA2wE # read it first
73
+ npx flostep step add Xk3p9QvA2wE "API -> Cache: read session"
74
+ npx flostep step add Xk3p9QvA2wE "Client -> API: retry" --at 3
75
+ npx flostep step rm Xk3p9QvA2wE 5
76
+ npx flostep node rename Xk3p9QvA2wE "Redis" "Session Cache"
77
77
  ```
78
78
 
79
79
  ### Folders
@@ -81,9 +81,9 @@ npx flostep node rename 42 "Redis" "Session Cache"
81
81
  Folders are shared by a team and addressed by name. File a diagram only when the user asks you to organise it:
82
82
 
83
83
  ```bash
84
- npx flostep folder list --json # names and diagram counts
85
- npx flostep folder create "Payments" # returns the folder if it already exists
86
- npx flostep move 42 "Payments" # file it; --none takes it out
84
+ npx flostep folder list --json # names and diagram counts
85
+ npx flostep folder create "Payments" # returns the folder if it already exists
86
+ npx flostep move Xk3p9QvA2wE "Payments" # file it; --none takes it out
87
87
  npx flostep list --folder "Payments" --json
88
88
  ```
89
89
 
@@ -92,11 +92,11 @@ npx flostep list --folder "Payments" --json
92
92
  ### Reading
93
93
 
94
94
  ```bash
95
- npx flostep list --json # ids, titles, urls
96
- npx flostep show 42 # the steps, plain text
97
- npx flostep step list 42 --json # numbered steps
98
- npx flostep node list 42 --json # components, first-appearance order
99
- npx flostep whoami --json # which workspace you're writing to
95
+ npx flostep list --json # ids, titles, urls
96
+ npx flostep show Xk3p9QvA2wE # the steps, plain text
97
+ npx flostep step list Xk3p9QvA2wE --json # numbered steps
98
+ npx flostep node list Xk3p9QvA2wE --json # components, first-appearance order
99
+ npx flostep whoami --json # which workspace you're writing to
100
100
  ```
101
101
 
102
102
  ### Rules
package/README.md CHANGED
@@ -20,14 +20,14 @@ Customer -> API: POST /checkout
20
20
  API -> Payments: charge card
21
21
  API -> Customer: order confirmed
22
22
  EOF
23
- # ✓ Created #42 Checkout
23
+ # ✓ Created #Xk3p9QvA2wE Checkout
24
24
  # https://flostep.dev/s/rEFdW8GSDwQ
25
25
  ```
26
26
 
27
27
  That wrote nothing to disk, and the id it printed is what every other command takes:
28
28
 
29
29
  ```bash
30
- npx flostep show 42 | sed 's/Payments/Stripe/' | npx flostep update 42
30
+ npx flostep show Xk3p9QvA2wE | sed 's/Payments/Stripe/' | npx flostep update Xk3p9QvA2wE
31
31
  ```
32
32
 
33
33
  ## The format
@@ -79,7 +79,7 @@ Ids come from `flostep list` or from `create`. Nothing is resolved from a file p
79
79
  There is no browser in CI, so the device flow doesn't apply. Create a key at [flostep.dev/api_keys](https://flostep.dev/api_keys) — leave its expiry as **Never**, since a key that lapses takes the pipeline down on a date nobody chose — and set it as `FLOSTEP_TOKEN`.
80
80
 
81
81
  ```yaml
82
- - run: npx flostep update 42 < docs/checkout.flostep
82
+ - run: npx flostep update Xk3p9QvA2wE < docs/checkout.flostep
83
83
  env:
84
84
  FLOSTEP_TOKEN: ${{ secrets.FLOSTEP_TOKEN }}
85
85
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flostep",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Build, update and share Flostep diagrams from the terminal, from CI, or from a coding agent.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -110,7 +110,7 @@ function topLevelHelp() {
110
110
  const starters = [
111
111
  ["flostep login", "sign in from a browser"],
112
112
  ['echo "A -> B: hello" | flostep create --share', "steps on stdin, returns a link"],
113
- ["flostep show 42 | flostep update 42", "read it, change it, write it back"],
113
+ ["flostep show Xk3p9QvA2wE | flostep update Xk3p9QvA2wE", "read it, change it, write it back"],
114
114
  ["flostep init", "teach this repo's coding agent to use flostep"]
115
115
  ];
116
116
  const starterWidth = Math.max(...starters.map(([command]) => command.length));
@@ -12,7 +12,7 @@ export default {
12
12
  name: "create",
13
13
  usage: [
14
14
  'flostep create [--title <title>] [--share] < steps.txt',
15
- 'flostep show 42 | flostep create --title "Copy"'
15
+ 'flostep show Xk3p9QvA2wE | flostep create --title "Copy"'
16
16
  ],
17
17
  details: [
18
18
  "Reads steps from stdin and creates a diagram. Writes no files.",
@@ -13,8 +13,8 @@ export default {
13
13
  options: { yes: { type: "boolean", short: "y", default: false } },
14
14
  optionHelp: [["-y, --yes", "skip the confirmation prompt"]],
15
15
  examples: [
16
- ["flostep delete 15"],
17
- ["flostep delete 15 --yes", "for scripts and agents"]
16
+ ["flostep delete Xk3p9QvA2wE"],
17
+ ["flostep delete Xk3p9QvA2wE --yes", "for scripts and agents"]
18
18
  ],
19
19
 
20
20
  async run({ positionals, values, ctx }) {
@@ -45,7 +45,7 @@ export default {
45
45
  }
46
46
 
47
47
  table(diagrams, [
48
- ["ID", (d) => d.id, "right"],
48
+ ["ID", (d) => d.id],
49
49
  ["TITLE", (d) => d.title],
50
50
  ["FOLDER", (d) => d.folder ?? ""],
51
51
  ["UPDATED", (d) => relativeTime(d.updated_at)],
@@ -17,8 +17,8 @@ export default {
17
17
  options: { none: { type: "boolean", default: false } },
18
18
  optionHelp: [["--none", "take the diagram out of its folder (uncategorized)"]],
19
19
  examples: [
20
- ['flostep move 42 "Payments"'],
21
- ["flostep move 42 --none"]
20
+ ['flostep move Xk3p9QvA2wE "Payments"'],
21
+ ["flostep move Xk3p9QvA2wE --none"]
22
22
  ],
23
23
 
24
24
  async run({ positionals, values, ctx }) {
@@ -7,7 +7,7 @@
7
7
  // way to express a type — the server infers that from the name. A `--type cache`
8
8
  // flag would be discarded on the next write, which is worse than not offering it.
9
9
  //
10
- // To add a component, name it in a step: `flostep step add 15 "API -> Redis: read"`.
10
+ // To add a component, name it in a step: `flostep step add Xk3p9QvA2wE "API -> Redis: read"`.
11
11
 
12
12
 
13
13
  import { UsageError } from "../errors.js";
@@ -29,9 +29,9 @@ export default {
29
29
  "Types (service, database, person…) are inferred from the name by the server."
30
30
  ],
31
31
  examples: [
32
- ["flostep node list 15"],
33
- ['flostep node rename 15 "Redis" "Session Cache"'],
34
- ["flostep node list 15 --json", "components in first-appearance order"]
32
+ ["flostep node list Xk3p9QvA2wE"],
33
+ ['flostep node rename Xk3p9QvA2wE "Redis" "Session Cache"'],
34
+ ["flostep node list Xk3p9QvA2wE --json", "components in first-appearance order"]
35
35
  ],
36
36
 
37
37
  async run({ positionals, ctx }) {
@@ -7,8 +7,8 @@ export default {
7
7
  usage: "flostep open <id>",
8
8
  details: ["Opens the diagram in the editor in your default browser."],
9
9
  examples: [
10
- ["flostep open 15"],
11
- ["flostep open 15 --json", "the url, and whether a browser started"]
10
+ ["flostep open Xk3p9QvA2wE"],
11
+ ["flostep open Xk3p9QvA2wE --json", "the url, and whether a browser started"]
12
12
  ],
13
13
 
14
14
  async run({ positionals, ctx }) {
@@ -48,10 +48,10 @@ export default {
48
48
  ["--markdown", "print a markdown image that links to the diagram (paid plans)"]
49
49
  ],
50
50
  examples: [
51
- ["flostep share 15"],
52
- ["flostep share 42 --embed", "for a docs page or Confluence"],
53
- ["flostep share 42 --markdown", "for a GitHub README; follows the diagram"],
54
- ["flostep share 15 --off"]
51
+ ["flostep share Xk3p9QvA2wE"],
52
+ ["flostep share Xk3p9QvA2wE --embed", "for a docs page or Confluence"],
53
+ ["flostep share Xk3p9QvA2wE --markdown", "for a GitHub README; follows the diagram"],
54
+ ["flostep share Xk3p9QvA2wE --off"]
55
55
  ],
56
56
 
57
57
  async run({ positionals, values, ctx }) {
@@ -6,12 +6,12 @@ export default {
6
6
  usage: "flostep show <id>",
7
7
  details: [
8
8
  "Prints the diagram as steps, and nothing else, so it pipes cleanly:",
9
- " flostep show 15 > docs/checkout.flostep"
9
+ " flostep show Xk3p9QvA2wE > docs/checkout.flostep"
10
10
  ],
11
11
  examples: [
12
- ["flostep show 15"],
13
- ["flostep show 42 > docs/checkout.flostep", "redirect it yourself if you want a file"],
14
- ["flostep show 15 --json", "with the title and url alongside the code"]
12
+ ["flostep show Xk3p9QvA2wE"],
13
+ ["flostep show Xk3p9QvA2wE > docs/checkout.flostep", "redirect it yourself if you want a file"],
14
+ ["flostep show Xk3p9QvA2wE --json", "with the title and url alongside the code"]
15
15
  ],
16
16
 
17
17
  async run({ positionals, ctx }) {
@@ -28,10 +28,10 @@ export default {
28
28
  options: { at: { type: "string" } },
29
29
  optionHelp: [["--at <n>", "insert before step n instead of appending"]],
30
30
  examples: [
31
- ['flostep step add 15 "API -> Cache: read session"'],
32
- ['flostep step add 15 "Client -> API: retry" --at 3'],
33
- ["flostep step list 15 --json"],
34
- ["flostep step rm 15 4"]
31
+ ['flostep step add Xk3p9QvA2wE "API -> Cache: read session"'],
32
+ ['flostep step add Xk3p9QvA2wE "Client -> API: retry" --at 3'],
33
+ ["flostep step list Xk3p9QvA2wE --json"],
34
+ ["flostep step rm Xk3p9QvA2wE 4"]
35
35
  ],
36
36
 
37
37
  async run({ positionals, values, ctx }) {
@@ -1,7 +1,7 @@
1
1
  // `flostep update` — replace a diagram's steps from a pipe.
2
2
  //
3
3
  // The counterpart to `create`, and the composable half of the tool:
4
- // flostep show 42 | sed 's/Redis/Session Cache/' | flostep update 42
4
+ // flostep show Xk3p9QvA2wE | sed 's/Redis/Session Cache/' | flostep update Xk3p9QvA2wE
5
5
 
6
6
  import { readStdin } from "../stdin.js";
7
7
  import { UsageError } from "../errors.js";
@@ -14,7 +14,7 @@ export default {
14
14
  name: "update",
15
15
  usage: [
16
16
  "flostep update <id> [--title <title>] [--if-version <n>] < steps.txt",
17
- "flostep show 42 | flostep update 42"
17
+ "flostep show Xk3p9QvA2wE | flostep update Xk3p9QvA2wE"
18
18
  ],
19
19
  details: [
20
20
  "Reads steps from stdin and replaces every step in the diagram.",
@@ -31,15 +31,15 @@ export default {
31
31
  ["--if-version <n>", "only write if the diagram is still at this version"]
32
32
  ],
33
33
  examples: [
34
- ["flostep show 42 | sed 's/Redis/Cache/' | flostep update 42"],
35
- ["flostep update 42 < revised.txt"],
36
- ["flostep update 42 --if-version 7 < revised.txt", "refused if it changed since version 7"]
34
+ ["flostep show Xk3p9QvA2wE | sed 's/Redis/Cache/' | flostep update Xk3p9QvA2wE"],
35
+ ["flostep update Xk3p9QvA2wE < revised.txt"],
36
+ ["flostep update Xk3p9QvA2wE --if-version 7 < revised.txt", "refused if it changed since version 7"]
37
37
  ],
38
38
 
39
39
  async run({ positionals, values, ctx }) {
40
40
  const { id } = resolveTarget(positionals[0]);
41
41
  const version = parseVersion(values["if-version"]);
42
- const input = await readStdin({ what: "`flostep update 42 < flow.txt`" });
42
+ const input = await readStdin({ what: "`flostep update Xk3p9QvA2wE < flow.txt`" });
43
43
  const { code, summary } = diagramFromStdin(input);
44
44
 
45
45
  const body = { code };
package/src/config.js CHANGED
@@ -9,8 +9,7 @@ import { homedir } from "node:os";
9
9
  import { join } from "node:path";
10
10
  import { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync } from "node:fs";
11
11
 
12
- // export const DEFAULT_HOST = "https://flostep.dev";
13
- export const DEFAULT_HOST = "http://localhost:3000";
12
+ export const DEFAULT_HOST = "https://flostep.dev";
14
13
 
15
14
  // XDG first, so anyone who has moved their config directory is respected;
16
15
  // ~/.config is the fallback rather than ~/.flostep because a dotfile per tool
package/src/target.js CHANGED
@@ -1,4 +1,4 @@
1
- // Turning "15" into a diagram id.
1
+ // Turning "Xk3_p9QvA2w" into a diagram id.
2
2
  //
3
3
  // Every command that acts on one diagram takes an id, and only an id. Diagrams
4
4
  // live in the account, not in a checkout: `create` and `update` read steps from
@@ -7,10 +7,13 @@
7
7
 
8
8
  import { UsageError } from "./errors.js";
9
9
 
10
- // A bare positive integer. Ids come from `flostep list`, from `create`, or
11
- // from the user — never from a guess.
10
+ // Any URL-safe token. Ids are random strings now; the integers servers used to
11
+ // hand out still resolve, so they pass too. This deliberately doesn't pin the
12
+ // server's exact format — when ids were checked as digits-only, changing the
13
+ // format would have broken every installed CLI. A wrong id is the server's 404
14
+ // to report; what this catches is a title passed where the id goes.
12
15
  export function looksLikeId(ref) {
13
- return /^[1-9][0-9]*$/.test(String(ref).trim());
16
+ return /^[A-Za-z0-9_-]+$/.test(String(ref).trim());
14
17
  }
15
18
 
16
19
  // Usage errors, not CliErrors: a missing or malformed id is the caller getting
@@ -25,9 +28,9 @@ export function resolveTarget(ref) {
25
28
 
26
29
  if (!looksLikeId(ref)) {
27
30
  throw new UsageError(`"${ref}" is not a diagram id.`, {
28
- hint: "Ids are numbers — run `flostep list` to see them."
31
+ hint: "Pass the ID column from `flostep list`, not the title."
29
32
  });
30
33
  }
31
34
 
32
- return { id: Number(ref) };
35
+ return { id: String(ref).trim() };
33
36
  }