@zhuk/spego 0.3.0 → 0.7.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0] - 2026-05-14
4
+
5
+ ### Changed
6
+ - **CLI output modes**: every command now emits pretty human-friendly output by default and JSON when the global `--json` flag is supplied. Human output uses bordered boxes (`╭─ ─╮`), aligned tables, single-emoji section headers (`📦 📄 🛠️ 🧭 📚 ✅`), and `────` dividers. Errors render as `⚠️ [CODE] message` in human mode and as the existing `{ error: { code, message, details } }` envelope in JSON mode.
7
+ - **`spego commands` and `spego workflows` default-mode flip**: these commands used to print JSON unconditionally; they now print human output by default. Agents and scripts that pipe their stdout MUST pass `--json` to keep getting JSON.
8
+ - **`spego regenerate` → `spego skills`**: renamed for clarity. `spego regenerate` remains as a hidden alias for one minor release with a deprecation warning. Running `spego skills` also cleans up any legacy `spego-regenerate` generated paths.
9
+
10
+ ### Deprecated
11
+ - **`spego view --format <fmt>`**: superseded by the global `--json` flag. Continues to work for one minor release; emits a single `deprecated:` warning line to stderr in human mode. Will be removed in the next minor release.
12
+ - **`spego regenerate`**: renamed to `spego skills`. The hidden alias continues to work for one minor release and emits a deprecation warning in human mode. Will be removed in the next minor release.
13
+
14
+ ## [0.6.2] - 2026-05-14
15
+
16
+ ### Fixed
17
+ - Replaced hardcoded local path in authoring workflow test with repo-relative root so tests pass on CI.
18
+ - Use lightweight git tag for npm trusted publishing (OIDC) compatibility.
19
+
20
+ ## [0.6.0] - 2026-05-13
21
+
22
+ ### Added
23
+ - `help` workflow: read-only orientation skill that inspects workspace state and recommends next steps via in-chat recommendations.
24
+ - `brainstorm-deep` workflow: single-persona, high-volume ideation targeting 50-100 ideas with clustering and ranking. Outputs `brainstorm` artifact.
25
+ - `elicit` workflow: iterative refinement using named methods (clarify, sharpen, generalize, specialize, stress-test, contextualize, simplify, formalize) with optimistic concurrency. Maximum 5 cycles per session.
26
+ - `kind` field on `WorkflowOutput` to distinguish `create`, `update`, and `none` output types.
27
+ - "Authoring loop" guidance and "brainstorm-deep vs brainstorm-party" matrix in README.
28
+ - Authoring workflow registry and content tests.
29
+
30
+ ## [0.5.0] - 2026-05-13
31
+
32
+ ### Added
33
+ - `review-edge-cases` workflow: method-driven edge-case enumeration (Path-tracer, Boundary-checker, Concurrency-skeptic personas). Outputs `qa` artifact with JSON findings array.
34
+ - `editorial-prose` workflow: clinical copy-edit pass (Copy-editor persona). Applies confirmed edits in place via `spego update --expected-revision`. Outputs `qa` summary artifact.
35
+ - `editorial-structure` workflow: structural review without mutation (Structural editor persona). Outputs `qa` artifact with prioritized restructuring recommendations.
36
+ - Review suite registry and content tests.
37
+ - "Complementary reviews" guidance in README.
38
+
39
+ ## [0.4.0] - 2026-05-12
40
+
41
+ ### Added
42
+ - Workflow skills as a first-class concept alongside command skills.
43
+ - `WORKFLOW_REGISTRY` with two reference workflows: `brainstorm-party` and `review-adversarial`.
44
+ - `spego workflows` command listing workflow metadata as JSON.
45
+ - Generator emits workflow skill files at `.claude/skills/spego-<workflow>/SKILL.md`.
46
+ - Legacy flat-file cleanup covers workflow skill names.
47
+ - Workflow and command skill coexistence tests, CLI tests, and legacy cleanup tests.
48
+
3
49
  ## [0.3.0] - 2026-05-11
4
50
 
5
51
  ### Changed
package/README.md CHANGED
@@ -22,13 +22,25 @@ spego init --agents claude --demo false
22
22
  | `spego delete --id <uuid>` | Soft-delete (preserves history) |
23
23
  | `spego list` | List artifacts |
24
24
  | `spego view` | Export bundle as markdown or JSON |
25
- | `spego commands` | List command metadata (JSON) |
26
- | `spego regenerate` | Regenerate agent skill files |
25
+ | `spego commands` | List command metadata |
26
+ | `spego workflows` | List workflow skills metadata |
27
+ | `spego skills` | Regenerate agent skill files |
27
28
  | `spego epics` | List delivery epics |
28
29
  | `spego tasks --change <name>` | List tasks for a change |
29
30
  | `spego index rebuild` | Rebuild SQLite index from files |
30
31
 
31
- All commands accept `--json` for structured output and `--cwd <dir>` to set the project root.
32
+ All commands accept `--cwd <dir>` to set the project root.
33
+
34
+ ### Output modes
35
+
36
+ Every spego command speaks two output modes:
37
+
38
+ - **Human (default)** — pretty, scannable output for terminals. Section headers use a single emoji prefix (`📦 📄 🛠️ 🧭 📚 ✅`), summaries render as bordered boxes (`╭─ … ─╮`), lists render as aligned tables, and `view` separates artifacts with `────` dividers. Errors print as `⚠️ [CODE] message` to stderr.
39
+ - **JSON (opt-in)** — pass the global `--json` flag to get deterministic, decoration-free JSON on stdout. Errors come back as `{ "error": { "code", "message", "details" } }` on stderr.
40
+
41
+ Agents calling spego MUST pass `--json` so they get parseable output. Humans normally do not.
42
+
43
+ The legacy `spego view --format markdown|json` flag is **deprecated** and will be removed in the next minor release. Use the global `--json` flag instead. The old flag still works during the deprecation window and prints a single `deprecated:` warning line to stderr.
32
44
 
33
45
  ## Architecture
34
46
 
@@ -67,7 +79,90 @@ For Claude agent targets, `spego init` generates:
67
79
  - `.claude/skills/spego-<command>/SKILL.md` — skill definitions following Claude Code conventions
68
80
  - `.claude/commands/spego/` — slash command wrappers
69
81
 
70
- Run `spego regenerate` to update generated files without reinitializing the workspace.
82
+ Run `spego skills` to update generated files without reinitializing the workspace.
83
+
84
+ ## Workflow Skills
85
+
86
+ Workflow skills guide an agent through a multi-persona process inside the chat, persisting results as spego artifacts at well-defined checkpoints.
87
+
88
+ ### brainstorm-party
89
+
90
+ Multi-persona collaborative brainstorming. Six roles (PM, Architect, UX, Dev, QA, Skeptic) take turns framing, expanding, challenging, and converging on ideas. Outputs a `brainstorm` artifact and optionally drafts a follow-up `prd` or `design`.
91
+
92
+ Use when exploring a problem space broadly or stress-testing a concept before committing.
93
+
94
+ ### review-adversarial
95
+
96
+ Adversarial critique of an existing artifact. Five roles (Skeptic, Security, Reliability, UX, Cost) attack from different angles, surface gaps, and prioritize findings. Outputs a `qa` or `risk` artifact and optionally a `decision` or `retro`.
97
+
98
+ Use when you need rigorous review before approval or implementation.
99
+
100
+ ### review-edge-cases
101
+
102
+ Method-driven edge-case enumeration. Three roles (Path-tracer, Boundary-checker, Concurrency-skeptic) mechanically trace branching paths, derive edge classes (off-by-one, unguarded inputs, missing else/default, race conditions, timeout gaps), filter already-handled cases, and report only unhandled paths. Outputs a `qa` artifact with a fenced JSON array of findings.
103
+
104
+ Use when you need to find logic defects that adversarial review may miss.
105
+
106
+ ### editorial-prose
107
+
108
+ Clinical copy-edit pass. A single Copy-editor persona identifies ambiguous sentences, unnecessary jargon, long sentences, passive voice, and redundancy. Confirmed edits are applied in place via `spego update` with `--expected-revision`; declined edits are recorded as recommendations. Outputs a `qa` artifact summarizing all edits.
109
+
110
+ Use when the artifact's ideas are sound but the prose needs tightening.
111
+
112
+ ### editorial-structure
113
+
114
+ Structural review without mutation. A single Structural editor persona outlines the current structure, proposes cuts/merges/reorders/splits, and produces a prioritized recommendation list. Does not modify the source artifact. Outputs a `qa` artifact with restructuring recommendations.
115
+
116
+ Use when content is correct but organization needs improvement.
117
+
118
+ ### help
119
+
120
+ Orientation workflow that reads workspace state and recommends next steps. A single Guide persona runs `spego status`, `spego list`, and `spego epics` to inspect the workspace, then applies a recommendation rubric to suggest the most impactful action. Produces no artifact — recommendations are delivered in chat only.
121
+
122
+ Use when starting a new session, unsure what to do next, or asking "what should I work on?".
123
+
124
+ ### brainstorm-deep
125
+
126
+ Single-persona, high-volume ideation targeting 50-100 ideas on a focused topic. One Ideator persona generates breadth, then clusters, deduplicates, and ranks the output. Outputs a `brainstorm` artifact.
127
+
128
+ Use when you have a focused problem and want maximum idea throughput without persona debate.
129
+
130
+ **When to use brainstorm-deep vs brainstorm-party:**
131
+
132
+ | Scenario | Use |
133
+ |----------|-----|
134
+ | Focused problem, need volume | `brainstorm-deep` |
135
+ | Broad problem, need diverse perspectives | `brainstorm-party` |
136
+ | One voice, fast iteration | `brainstorm-deep` |
137
+ | Multiple viewpoints, stress-test ideas | `brainstorm-party` |
138
+
139
+ ### elicit
140
+
141
+ Iterative refinement of an existing artifact using named methods (clarify, sharpen, generalize, specialize, stress-test, contextualize, simplify, formalize). A single Refiner persona proposes changes, confirms with the user, and applies via `spego update --expected-revision`. Maximum 5 cycles per session. Outputs a `qa` summary and in-place updates of the source artifact.
142
+
143
+ Use when you have a draft that needs systematic improvement.
144
+
145
+ ### Authoring loop
146
+
147
+ The recommended authoring sequence combines all workflow skills:
148
+
149
+ 1. **Orient** — Run `spego-help` to understand workspace state and get recommendations.
150
+ 2. **Ideate** — Run `spego-brainstorm-party` (multi-perspective breadth) or `spego-brainstorm-deep` (single-voice volume) to explore the problem space.
151
+ 3. **Capture** — Run `spego create --type prd` (or `architecture`, `design`, etc.) to persist the output.
152
+ 4. **Refine** — Run `spego-elicit` to iteratively improve the draft with structured methods.
153
+ 5. **Review** — Run `spego-review-adversarial` and `spego-review-edge-cases` for technical coverage, or `spego-editorial-prose` / `spego-editorial-structure` for communication quality.
154
+
155
+ ### Invocation
156
+
157
+ All workflow skills are generated at `.claude/skills/spego-<workflow>/SKILL.md` during `spego init`. The agent picks them up automatically based on the skill description.
158
+
159
+ ### Complementary reviews
160
+
161
+ For thorough artifact review, combine reviewers for orthogonal coverage:
162
+
163
+ - **Technical defects:** Run `review-adversarial` (attitude-driven: hunts for gaps, weak assumptions) and `review-edge-cases` (method-driven: enumerates unhandled branching paths). Together they catch almost all technical defects.
164
+ - **Communication defects:** Run `editorial-prose` (copy-edit) and `editorial-structure` (organizational review). These catch confusion, ambiguity, and poor organization that technical reviewers don't flag.
165
+ - **Recommended minimum:** At least one technical reviewer + at least one editorial reviewer before declaring an artifact ready.
71
166
 
72
167
  ## Development
73
168
 
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Pretty-rendering primitives for the spego CLI human output mode.
3
+ *
4
+ * All functions are pure: string in, string out. They MUST NOT read
5
+ * `process.env`, MUST NOT detect TTY, and MUST NOT emit ANSI color codes.
6
+ * Output is plain text plus a small fixed set of Unicode box-drawing and
7
+ * arrow characters so it stays scannable, copy-pasteable, and stable across
8
+ * terminals.
9
+ */
10
+ /** Truncate `value` to fit within `width` characters, appending `…` when cut. */
11
+ export declare function truncate(value: string, width: number): string;
12
+ /** Right-pad `value` with spaces to `width` characters. Strings longer than `width` are returned unchanged. */
13
+ export declare function padRight(value: string, width: number): string;
14
+ /**
15
+ * Render a bordered key/value summary box using rounded box-drawing characters.
16
+ *
17
+ * ```
18
+ * ╭─ Workspace ─────────────────────────╮
19
+ * │ root /tmp/proj │
20
+ * │ agents claude │
21
+ * ╰─────────────────────────────────────╯
22
+ * ```
23
+ */
24
+ export declare function renderBox(title: string, rows: Array<[string, string]>): string;
25
+ /**
26
+ * Render an aligned table with a header row separated from data rows by `─`.
27
+ *
28
+ * ```
29
+ * type/slug rev title
30
+ * ───────────── ─── ──────────────
31
+ * prd/test-prd 1 Test PRD
32
+ * ```
33
+ *
34
+ * `opts.maxWidth` caps each column width and truncates longer cells with `…`
35
+ * (default 60). An empty `rows` array still renders the header and divider
36
+ * so callers can prepend a "no rows" hint above if they choose.
37
+ */
38
+ export declare function renderTable(columns: string[], rows: string[][], opts?: {
39
+ maxWidth?: number;
40
+ }): string;
41
+ /** Render a single-line section header prefixed by an emoji. */
42
+ export declare function renderHeader(emoji: string, label: string): string;
43
+ /** Render a `─` divider of the given width (default 60). */
44
+ export declare function renderDivider(width?: number): string;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Pretty-rendering primitives for the spego CLI human output mode.
3
+ *
4
+ * All functions are pure: string in, string out. They MUST NOT read
5
+ * `process.env`, MUST NOT detect TTY, and MUST NOT emit ANSI color codes.
6
+ * Output is plain text plus a small fixed set of Unicode box-drawing and
7
+ * arrow characters so it stays scannable, copy-pasteable, and stable across
8
+ * terminals.
9
+ */
10
+ const DEFAULT_TABLE_MAX_WIDTH = 60;
11
+ /** Truncate `value` to fit within `width` characters, appending `…` when cut. */
12
+ export function truncate(value, width) {
13
+ if (width <= 0)
14
+ return '';
15
+ if (value.length <= width)
16
+ return value;
17
+ if (width === 1)
18
+ return '…';
19
+ return value.slice(0, width - 1) + '…';
20
+ }
21
+ /** Right-pad `value` with spaces to `width` characters. Strings longer than `width` are returned unchanged. */
22
+ export function padRight(value, width) {
23
+ if (value.length >= width)
24
+ return value;
25
+ return value + ' '.repeat(width - value.length);
26
+ }
27
+ /**
28
+ * Render a bordered key/value summary box using rounded box-drawing characters.
29
+ *
30
+ * ```
31
+ * ╭─ Workspace ─────────────────────────╮
32
+ * │ root /tmp/proj │
33
+ * │ agents claude │
34
+ * ╰─────────────────────────────────────╯
35
+ * ```
36
+ */
37
+ export function renderBox(title, rows) {
38
+ const keyWidth = rows.reduce((m, [k]) => Math.max(m, k.length), 0);
39
+ const valueWidth = rows.reduce((m, [, v]) => Math.max(m, v.length), 0);
40
+ // Inner content width: key + 2 spaces + value
41
+ const contentWidth = Math.max(keyWidth + 2 + valueWidth, title.length + 4);
42
+ const innerWidth = contentWidth + 2; // 1 space padding on each side
43
+ // Title row: `╭─ <title> <N×─>╮`. Body row width is `contentWidth + 4`
44
+ // (`│ ` + content + ` │`); title row width is `5 + title.length + N`,
45
+ // so N = contentWidth - title.length - 1 to keep both rows equal.
46
+ const titleLine = `╭─ ${title} ${'─'.repeat(Math.max(0, contentWidth - title.length - 1))}╮`;
47
+ const bottom = `╰${'─'.repeat(innerWidth)}╯`;
48
+ const body = rows
49
+ .map(([k, v]) => {
50
+ const line = `${padRight(k, keyWidth)} ${v}`;
51
+ return `│ ${padRight(line, contentWidth)} │`;
52
+ })
53
+ .join('\n');
54
+ return rows.length === 0 ? `${titleLine}\n${bottom}` : `${titleLine}\n${body}\n${bottom}`;
55
+ }
56
+ /**
57
+ * Render an aligned table with a header row separated from data rows by `─`.
58
+ *
59
+ * ```
60
+ * type/slug rev title
61
+ * ───────────── ─── ──────────────
62
+ * prd/test-prd 1 Test PRD
63
+ * ```
64
+ *
65
+ * `opts.maxWidth` caps each column width and truncates longer cells with `…`
66
+ * (default 60). An empty `rows` array still renders the header and divider
67
+ * so callers can prepend a "no rows" hint above if they choose.
68
+ */
69
+ export function renderTable(columns, rows, opts = {}) {
70
+ const maxWidth = opts.maxWidth ?? DEFAULT_TABLE_MAX_WIDTH;
71
+ const widths = columns.map((col, i) => {
72
+ const dataMax = rows.reduce((m, r) => Math.max(m, (r[i] ?? '').length), 0);
73
+ const target = Math.max(col.length, dataMax);
74
+ return Math.min(target, maxWidth);
75
+ });
76
+ const formatRow = (cells) => widths.map((w, i) => padRight(truncate(cells[i] ?? '', w), w)).join(' ').trimEnd();
77
+ const header = formatRow(columns);
78
+ const divider = widths.map((w) => '─'.repeat(w)).join(' ').trimEnd();
79
+ const body = rows.map(formatRow).join('\n');
80
+ return rows.length === 0 ? `${header}\n${divider}` : `${header}\n${divider}\n${body}`;
81
+ }
82
+ /** Render a single-line section header prefixed by an emoji. */
83
+ export function renderHeader(emoji, label) {
84
+ return `${emoji} ${label}`;
85
+ }
86
+ /** Render a `─` divider of the given width (default 60). */
87
+ export function renderDivider(width = 60) {
88
+ return '─'.repeat(Math.max(1, width));
89
+ }
90
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/cli/render.ts"],"names":[],"mappings":"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"}