smashspace 0.1.7 → 0.1.9

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 (3) hide show
  1. package/README.md +18 -7
  2. package/dist/smash.mjs +36 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,11 +34,17 @@ server below. (Headless? use `smash login --token <PAT>`.)
34
34
 
35
35
  ## Onboard a project for agents: `smash init`
36
36
 
37
- Run once per repo to scaffold everything agents (Claude Code / Codex) need to
38
- operate SmashSpace as the task backbone — no manual copying:
37
+ **One project = one `smash init` = one space.** Run it once inside each repo, so
38
+ that project's agents (Claude Code / Codex) operate their own space:
39
39
 
40
40
  ```bash
41
- smash init --board-id b_xxxxxxxx
41
+ cd your/dir/project
42
+
43
+ # create a new space and pin it to this project
44
+ smash init --new-space "Your Project"
45
+
46
+ # …or pin an existing space
47
+ smash init --space-id s_xxxxxxxx
42
48
  ```
43
49
 
44
50
  It writes (and is safe to re-run — existing config is kept unless `--force`):
@@ -46,12 +52,17 @@ It writes (and is safe to re-run — existing config is kept unless `--force`):
46
52
  - `.claude/skills/smash/SKILL.md` + `.codex/skills/smash/SKILL.md` — the
47
53
  SmashSpace Operator playbook (CLI/MCP usage + Inbox→Todo→Doing→Review→Done
48
54
  workflow + safety rules). Always refreshed to the installed CLI version.
49
- - `.smashspace.json` — pins the instance + board.
55
+ - `.smashspace.json` — pins the instance + space (which space this dir talks to).
50
56
  - `.mcp.json` — wires the `smashspace` MCP server (merged, other servers kept).
51
57
 
52
- Flags: `--skills-only` (just the operator skill), `--no-mcp`, `--force`,
53
- `--board-id <id>`. Then `smash login` once on the machine and the agents are
54
- ready.
58
+ Plain `smash init` (no space flag) doesn't guess: it prints how to specify a
59
+ space (`--new-space` / `--space-id`) and exits without writing anything. Same,
60
+ predictable behaviour in a terminal, an agent, or CI — nothing hangs, nothing is
61
+ written half-way. (`--skills-only` installs just the skill, no space needed.)
62
+
63
+ Flags: `--new-space <name>`, `--space-id <id>` (`--board-id` is a legacy alias),
64
+ `--skills-only` (just the operator skill), `--no-mcp`, `--force`. Sign in once
65
+ with `smash login` first (`--new-space` needs it).
55
66
 
56
67
  ## Project config: `.smashspace.json`
57
68
 
package/dist/smash.mjs CHANGED
@@ -4763,7 +4763,7 @@ program2.command("status").aliases(["context", "where"]).description(
4763
4763
  });
4764
4764
  program2.command("init").description(
4765
4765
  "Scaffold this project for agents: operator skill + .smashspace.json + .mcp.json"
4766
- ).option("--board-id <id>", "Board/space id to pin in .smashspace.json / .mcp.json").option("--skills-only", "Only (re)install the operator skill files").option("--no-mcp", "Skip writing .mcp.json").option("-f, --force", "Overwrite .smashspace.json / .mcp.json if they exist").action(
4766
+ ).option("--new-space <name>", "create a new space with this name, then pin it (needs login)").option("--space-id <id>", "existing space id to pin, e.g. s_xxxxxxxx").option("--board-id <id>", "alias for --space-id (legacy)").option("--skills-only", "Only (re)install the operator skill files").option("--no-mcp", "Skip writing .mcp.json").option("-f, --force", "Overwrite .smashspace.json / .mcp.json if they exist").action(
4767
4767
  async (opts) => {
4768
4768
  const cwd = process.cwd();
4769
4769
  const actions = [];
@@ -4781,23 +4781,45 @@ program2.command("init").description(
4781
4781
  return false;
4782
4782
  }
4783
4783
  };
4784
+ const baseUrl = resolveBaseUrl();
4785
+ if (!opts.skillsOnly && !opts.newSpace && !opts.spaceId && !opts.boardId) {
4786
+ console.error(
4787
+ [
4788
+ "\u30B9\u30DA\u30FC\u30B9\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002\u6B21\u306E\u3069\u3061\u3089\u304B\u3092\u4ED8\u3051\u3066\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044:",
4789
+ "",
4790
+ ' smash init --new-space "Your Project" # \u65B0\u3057\u304F\u4F5C\u3063\u3066\u7D50\u3073\u3064\u3051\u308B',
4791
+ " smash init --space-id s_xxxxxxxx # \u65E2\u5B58\u306E\u30B9\u30DA\u30FC\u30B9\u306B\u7D50\u3073\u3064\u3051\u308B",
4792
+ "",
4793
+ "\u65E2\u5B58\u30B9\u30DA\u30FC\u30B9\u306E id \u306F `smash space list` \u3067\u78BA\u8A8D\u3067\u304D\u307E\u3059\u3002",
4794
+ "\u30B9\u30AD\u30EB\u3060\u3051\u5165\u308C\u305F\u3044\u5834\u5408\u306F `smash init --skills-only`\u3002"
4795
+ ].join("\n")
4796
+ );
4797
+ process.exit(1);
4798
+ }
4784
4799
  await put(".claude/skills/smash/SKILL.md", SMASH_SKILL_MD);
4785
4800
  await put(".codex/skills/smash/SKILL.md", SMASH_SKILL_MD);
4786
4801
  await put(".codex/skills/smash/agents/openai.yaml", OPENAI_AGENT_YAML);
4787
- actions.push(
4788
- "\u2713 operator skill \u2192 .claude/skills/smash/ + .codex/skills/smash/"
4789
- );
4790
- const baseUrl = resolveBaseUrl();
4791
- const boardId = opts.boardId ?? "b_xxxxxxxx";
4792
- const placeholder = boardId === "b_xxxxxxxx";
4802
+ actions.push("\u2713 operator skill \u2192 .claude/skills/smash/ + .codex/skills/smash/");
4803
+ let boardId = "";
4804
+ if (!opts.skillsOnly) {
4805
+ if (opts.newSpace) {
4806
+ const space = await api(
4807
+ "/api/boards",
4808
+ { method: "POST", body: JSON.stringify({ title: opts.newSpace }) },
4809
+ baseUrl
4810
+ );
4811
+ boardId = space.id;
4812
+ actions.push(`\u2713 created space "${space.title || opts.newSpace}" (${space.id})`);
4813
+ } else {
4814
+ boardId = opts.spaceId ?? opts.boardId;
4815
+ }
4816
+ }
4793
4817
  if (!opts.skillsOnly) {
4794
4818
  if (await exists(CONFIG_FILENAME) && !opts.force) {
4795
4819
  actions.push(`\u2022 ${CONFIG_FILENAME} exists \u2014 kept (use --force)`);
4796
4820
  } else {
4797
4821
  await put(CONFIG_FILENAME, smashspaceJson(baseUrl, boardId));
4798
- actions.push(
4799
- `\u2713 ${CONFIG_FILENAME}${placeholder ? " (placeholder space_id \u2014 edit it)" : ` (${boardId})`}`
4800
- );
4822
+ actions.push(`\u2713 ${CONFIG_FILENAME} \u2192 ${boardId}`);
4801
4823
  }
4802
4824
  if (opts.mcp !== false) {
4803
4825
  let mcp = { mcpServers: {} };
@@ -4831,15 +4853,15 @@ program2.command("init").description(
4831
4853
  }
4832
4854
  }
4833
4855
  }
4834
- const next = ["", "Next:", " 1. smash login # sign in (browser approval)"];
4835
- if (!opts.skillsOnly && placeholder) {
4836
- next.push(" 2. edit .smashspace.json # set your real space_id (`smash board list` to find it)");
4856
+ const next = ["", "Next:"];
4857
+ if (!opts.skillsOnly) {
4858
+ next.push(" smash login # if you haven't yet \u2014 then you're ready.");
4837
4859
  }
4838
4860
  next.push(
4839
4861
  " \u2192 Claude Code / Codex pick up .claude|.codex/skills/smash automatically"
4840
4862
  );
4841
4863
  if (getOpts().json) {
4842
- show({ cwd, actions, baseUrl, boardId: placeholder ? null : boardId });
4864
+ show({ cwd, actions, baseUrl, boardId: boardId || null });
4843
4865
  return;
4844
4866
  }
4845
4867
  show(void 0, [...actions, ...next]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smashspace",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "SmashSpace CLI + MCP — operate SmashSpace boards from your terminal, Claude Code, Cursor, and Codex.",
5
5
  "type": "module",
6
6
  "bin": {