big-tools 0.0.1
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/LICENSE +26 -0
- package/PRIVACY.md +81 -0
- package/README.md +112 -0
- package/corpus/CONTRIBUTORS.md +35 -0
- package/corpus/LICENSE +22 -0
- package/dist/cli.js +100 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/between-sessions.js +10 -0
- package/dist/commands/between-sessions.js.map +1 -0
- package/dist/commands/config.js +54 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/delphi.js +10 -0
- package/dist/commands/delphi.js.map +1 -0
- package/dist/commands/discovery-actionability.js +15 -0
- package/dist/commands/discovery-actionability.js.map +1 -0
- package/dist/commands/easy-on-people.js +9 -0
- package/dist/commands/easy-on-people.js.map +1 -0
- package/dist/commands/ideawriting.js +7 -0
- package/dist/commands/ideawriting.js.map +1 -0
- package/dist/commands/ngt.js +49 -0
- package/dist/commands/ngt.js.map +1 -0
- package/dist/commands/paper-house.js +44 -0
- package/dist/commands/paper-house.js.map +1 -0
- package/dist/commands/selfish-explorer.js +9 -0
- package/dist/commands/selfish-explorer.js.map +1 -0
- package/dist/lib/big-template.js +165 -0
- package/dist/lib/big-template.js.map +1 -0
- package/dist/lib/config-store.js +64 -0
- package/dist/lib/config-store.js.map +1 -0
- package/dist/lib/corpus.js +21 -0
- package/dist/lib/corpus.js.map +1 -0
- package/dist/lib/format.js +14 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/plm-types.js +17 -0
- package/dist/lib/plm-types.js.map +1 -0
- package/dist/lib/provider.js +270 -0
- package/dist/lib/provider.js.map +1 -0
- package/dist/lib/queue.js +31 -0
- package/dist/lib/queue.js.map +1 -0
- package/dist/lib/resolve-provider.js +49 -0
- package/dist/lib/resolve-provider.js.map +1 -0
- package/dist/lib/retry.js +219 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/style-audit.js +20 -0
- package/dist/lib/style-audit.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stephen Szermer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
NOTE: The `corpus/` directory contains content under a separate license
|
|
26
|
+
(CC-BY-NC-SA 4.0 proposed, pending review). See `corpus/LICENSE` for details.
|
package/PRIVACY.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Privacy — big-tools
|
|
2
|
+
|
|
3
|
+
big-tools runs on your own computer. This document explains, in plain English,
|
|
4
|
+
exactly what data moves where when you use it.
|
|
5
|
+
|
|
6
|
+
## What leaves your machine
|
|
7
|
+
|
|
8
|
+
Only one thing: **the prompt text you send to the language model you chose**.
|
|
9
|
+
|
|
10
|
+
When you run a command like `big-tools ngt "your idea here"`, big-tools sends
|
|
11
|
+
your prompt to the LLM provider you configured (OpenRouter, OpenAI, Anthropic,
|
|
12
|
+
Google, or a local Ollama instance). That provider processes the request
|
|
13
|
+
according to *their* privacy policy, which you should read separately.
|
|
14
|
+
|
|
15
|
+
big-tools itself does not receive, log, store, or forward your prompts.
|
|
16
|
+
|
|
17
|
+
## What never leaves your machine
|
|
18
|
+
|
|
19
|
+
- The shipped **corpus** (`corpus/` directory). Search happens locally; the
|
|
20
|
+
corpus is never uploaded anywhere.
|
|
21
|
+
- Your **configuration** (`~/.config/big-tools/config.json`). This file holds
|
|
22
|
+
your API key and default model. It is read by the CLI on startup and never
|
|
23
|
+
sent anywhere else.
|
|
24
|
+
- Any **session notes** or files you pass with `--sessions-dir`. These are
|
|
25
|
+
read by the Between Sessions tool to draft an opener. The file contents may
|
|
26
|
+
be included in the prompt sent to your LLM provider (so they read it), but
|
|
27
|
+
big-tools does not store or forward them elsewhere.
|
|
28
|
+
- Your **command history**. Not logged by big-tools.
|
|
29
|
+
|
|
30
|
+
## No telemetry
|
|
31
|
+
|
|
32
|
+
big-tools has zero telemetry. No usage reporting, no error reporting, no crash
|
|
33
|
+
reporting, no analytics, no callbacks. The only outbound network traffic is
|
|
34
|
+
the HTTPS request to the LLM provider API you configured.
|
|
35
|
+
|
|
36
|
+
You can verify this yourself: the source code is in the repo, search for
|
|
37
|
+
`fetch` and you will find only one call site (the provider module) and it only
|
|
38
|
+
targets the configured LLM provider.
|
|
39
|
+
|
|
40
|
+
## How to revoke
|
|
41
|
+
|
|
42
|
+
To completely remove big-tools and your configuration:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
npm uninstall -g big-tools
|
|
46
|
+
rm -rf ~/.config/big-tools
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
To rotate or remove your API key without uninstalling:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
big-tools config set openrouter-key "" # clear the stored key
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## A note for the Brown Practicum class
|
|
56
|
+
|
|
57
|
+
If you are a student in the Brown Practicum "Ways to Discover a Good Idea,"
|
|
58
|
+
the only content big-tools comes with out of the box is what Stephen (and
|
|
59
|
+
optionally Chris) has explicitly contributed to the shipped corpus. No student
|
|
60
|
+
content is included. If the class later decides to add shared student
|
|
61
|
+
contributions, that will happen only with individual written opt-in from each
|
|
62
|
+
contributing student — see `corpus/CONTRIBUTORS.md`.
|
|
63
|
+
|
|
64
|
+
## Export compliance
|
|
65
|
+
|
|
66
|
+
big-tools is open-source JavaScript that makes standard HTTPS API calls to
|
|
67
|
+
commercial LLM providers. It contains no cryptographic software beyond
|
|
68
|
+
standard TLS, does not train or distribute model weights, and is not subject
|
|
69
|
+
to US EAR 5D002 or the AI Diffusion Framework. Students outside the United
|
|
70
|
+
States — including students at Ben-Gurion University — can install and use
|
|
71
|
+
big-tools without export restriction.
|
|
72
|
+
|
|
73
|
+
If your institution has its own AI-use or data-handling policies, those
|
|
74
|
+
supersede anything in this document. Check with your local IT or academic
|
|
75
|
+
office before using big-tools in coursework.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
*Last updated: 2026-04-15. If you spot anything in this document that
|
|
80
|
+
contradicts how the code actually behaves, please open an issue — privacy
|
|
81
|
+
claims are worth more when they are verifiable.*
|
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# big-tools
|
|
2
|
+
|
|
3
|
+
Small tools for bigger ideas — between sessions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What this is
|
|
8
|
+
|
|
9
|
+
Four phases. Eight tools. One terminal command.
|
|
10
|
+
|
|
11
|
+
Every good idea goes through four phases — you **generate** it, you **develop**
|
|
12
|
+
it, you **select** which ones to act on, and you **promote** the ones you kept.
|
|
13
|
+
This is Carl Moore's BIG methodology, and it has been running groups to better
|
|
14
|
+
ideas for forty years.
|
|
15
|
+
|
|
16
|
+
big-tools gives you small helpers for the work that happens between sessions —
|
|
17
|
+
when the room is empty, the whiteboard has been erased, and the ideas need
|
|
18
|
+
somewhere to live until the next time you meet.
|
|
19
|
+
|
|
20
|
+
| Phase | Tools |
|
|
21
|
+
| --------- | ----------------------------------------------------------------- |
|
|
22
|
+
| Generate | NGT Round-Robin · Ideawriting · Selfish Explorer |
|
|
23
|
+
| Develop | Paper House · Delphi Rounds |
|
|
24
|
+
| Select | Discovery × Actionability |
|
|
25
|
+
| Promote | Easy on People · Between Sessions |
|
|
26
|
+
|
|
27
|
+
Each tool is named after something a facilitator already does. The tool does
|
|
28
|
+
not replace the facilitator. It just remembers what happened, and stands ready
|
|
29
|
+
for the next time.
|
|
30
|
+
|
|
31
|
+
You run them on your own computer. Nothing you type goes anywhere except to
|
|
32
|
+
the language model you choose.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Setup (technical section)
|
|
37
|
+
|
|
38
|
+
Everything below this line is for students who want to install the package and
|
|
39
|
+
connect it to their preferred LLM client. If you are a teacher or facilitator
|
|
40
|
+
planning to use big-tools in a class, you can stop reading here — the setup
|
|
41
|
+
work is a one-time step your students will do themselves.
|
|
42
|
+
|
|
43
|
+
### Install
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npx big-tools@latest --help
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That prints the eight tools and shows you how to run each one.
|
|
50
|
+
|
|
51
|
+
### Bring your own model
|
|
52
|
+
|
|
53
|
+
big-tools does not include a language model. You supply one. Three options:
|
|
54
|
+
|
|
55
|
+
**Option 1 — OpenRouter (recommended, free-tier available)**. OpenRouter
|
|
56
|
+
routes to dozens of models through a single API key, including free-tier
|
|
57
|
+
models that cost nothing to run for classroom-scale use.
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
# 1. Sign up at https://openrouter.ai (free)
|
|
61
|
+
# 2. Create an API key
|
|
62
|
+
# 3. Tell big-tools about it:
|
|
63
|
+
big-tools config set openrouter-key sk-or-v1-...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Option 2 — Use a key you already have**. If you already pay for OpenAI,
|
|
67
|
+
Anthropic, or Google, big-tools will pick up their environment variables
|
|
68
|
+
automatically. Nothing to configure.
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY, or GOOGLE_API_KEY
|
|
72
|
+
big-tools ngt "a prompt"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Option 3 — Run locally with Ollama** (offline, free, slower). Install
|
|
76
|
+
[Ollama](https://ollama.com), pull a small instruction-tuned model, and tell
|
|
77
|
+
big-tools to use it:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
ollama pull llama3.1:8b
|
|
81
|
+
export OLLAMA_HOST=http://localhost:11434
|
|
82
|
+
big-tools config set model ollama/llama3.1:8b
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Run a tool
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
big-tools ngt "What's an unfamiliar way to lower criticality during a first draft?"
|
|
89
|
+
big-tools delphi "The Parking Lot should require structured tags before a Monday debrief"
|
|
90
|
+
big-tools between-sessions --sessions-dir ./class-notes
|
|
91
|
+
big-tools --help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Every tool accepts `--json` for scripting and `--model <id>` for one-off model
|
|
95
|
+
overrides.
|
|
96
|
+
|
|
97
|
+
### Privacy
|
|
98
|
+
|
|
99
|
+
Read [`PRIVACY.md`](./PRIVACY.md) before you use the package in a class. Short
|
|
100
|
+
version: big-tools runs entirely on your computer. The only thing that leaves
|
|
101
|
+
your machine is the prompt text you send to the LLM provider you already
|
|
102
|
+
chose. There is no telemetry, no hosted corpus, no student database.
|
|
103
|
+
|
|
104
|
+
### License
|
|
105
|
+
|
|
106
|
+
Code is MIT. The corpus in `corpus/` is under a separate license — see
|
|
107
|
+
`corpus/LICENSE` for details.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
*big-tools is a project of the Brown Practicum "Ways to Discover a Good Idea"
|
|
112
|
+
(Spring 2026).*
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Corpus Contributors
|
|
2
|
+
|
|
3
|
+
Every file under `corpus/` has a contributor of record. This document is the
|
|
4
|
+
audit log of who contributed what, when, and under what scope.
|
|
5
|
+
|
|
6
|
+
## Scope tags
|
|
7
|
+
|
|
8
|
+
Each corpus file declares a `scope_tag` in its YAML frontmatter:
|
|
9
|
+
|
|
10
|
+
| Tag | Meaning |
|
|
11
|
+
| --------------- | ----------------------------------------------------------- |
|
|
12
|
+
| `public` | Contributor owns the content and releases it publicly |
|
|
13
|
+
| `stephen-only` | Committed by Stephen; redistributable under package license |
|
|
14
|
+
| `class-opt-in` | Contributed by a class member with individual written opt-in |
|
|
15
|
+
|
|
16
|
+
## Phase 1 (2026-04-15 onward) — Stephen only
|
|
17
|
+
|
|
18
|
+
Stephen Szermer is committing his own materials to seed the corpus before any
|
|
19
|
+
student content is ingested. No Phase 2 (student) contributions until explicit
|
|
20
|
+
written consent workflow is in place (tracked in `corpus/OPT-IN-WORKFLOW.md`,
|
|
21
|
+
to be written before any student contribution is accepted).
|
|
22
|
+
|
|
23
|
+
### Files committed
|
|
24
|
+
|
|
25
|
+
(Populated as files are added.)
|
|
26
|
+
|
|
27
|
+
| File | Contributor | Date | Scope | Notes |
|
|
28
|
+
|------|-------------|------|-------|-------|
|
|
29
|
+
| *(none yet — scaffold stage)* | | | | |
|
|
30
|
+
|
|
31
|
+
## Revocation
|
|
32
|
+
|
|
33
|
+
If a contributor later wants their content removed from the corpus, they can
|
|
34
|
+
open a GitHub issue or email the maintainer. Removed content will be deleted
|
|
35
|
+
in the next package release.
|
package/corpus/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Corpus License — CC BY-NC-SA 4.0 (proposed, pending review)
|
|
2
|
+
|
|
3
|
+
The content in the `corpus/` directory of the big-tools package is licensed
|
|
4
|
+
under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
|
5
|
+
(CC BY-NC-SA 4.0) — https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
6
|
+
|
|
7
|
+
Summary (this is not the license itself — see the full text at the URL above):
|
|
8
|
+
|
|
9
|
+
- **BY** — You must give appropriate credit to the original contributors
|
|
10
|
+
- **NC** — You may not use the material for commercial purposes
|
|
11
|
+
- **SA** — If you remix or build on the material, you must share under the
|
|
12
|
+
same license
|
|
13
|
+
|
|
14
|
+
The package code in `src/` and `dist/` is licensed separately under MIT — see
|
|
15
|
+
the top-level `LICENSE` file.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
NOTE: This license is a proposed default. The final license will be decided
|
|
20
|
+
during review with the Brown Practicum faculty (Chris Moore) before the
|
|
21
|
+
package is published publicly. If you are reading this before that review has
|
|
22
|
+
happened, treat the corpus as "not yet cleared for redistribution."
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { ngt } from "./commands/ngt.js";
|
|
4
|
+
import { ideawriting } from "./commands/ideawriting.js";
|
|
5
|
+
import { paperHouse } from "./commands/paper-house.js";
|
|
6
|
+
import { easyOnPeople } from "./commands/easy-on-people.js";
|
|
7
|
+
import { delphi } from "./commands/delphi.js";
|
|
8
|
+
import { discoveryActionability } from "./commands/discovery-actionability.js";
|
|
9
|
+
import { selfishExplorer } from "./commands/selfish-explorer.js";
|
|
10
|
+
import { betweenSessions } from "./commands/between-sessions.js";
|
|
11
|
+
import { config } from "./commands/config.js";
|
|
12
|
+
const program = new Command();
|
|
13
|
+
program
|
|
14
|
+
.name("big-tools")
|
|
15
|
+
.description("Between-sessions tools for Better Idea Generation.\n" +
|
|
16
|
+
"Four phases, eight tools: Generate, Develop, Select, Promote.")
|
|
17
|
+
.version("0.0.1");
|
|
18
|
+
// ─── GENERATE ──────────────────────────────────────────────────────────────
|
|
19
|
+
program
|
|
20
|
+
.command("ngt")
|
|
21
|
+
.description("[Generate] Nominal Group Technique — silent parallel generation, round-robin presentation")
|
|
22
|
+
.argument("<prompt>", "the generation brief")
|
|
23
|
+
.option("-n, --n <count>", "number of responders", "5")
|
|
24
|
+
.option("--parallel", "run concurrent instead of serial (risk rate limits)", false)
|
|
25
|
+
.option("--json", "emit JSON", false)
|
|
26
|
+
.option("--model <id>", "override model for this call")
|
|
27
|
+
.action(ngt);
|
|
28
|
+
program
|
|
29
|
+
.command("ideawriting")
|
|
30
|
+
.description("[Generate] Ideawriting — silent written brainstorm, N variants passed before review")
|
|
31
|
+
.argument("<prompt>", "the generation brief")
|
|
32
|
+
.option("-n, --n <count>", "number of variants", "5")
|
|
33
|
+
.option("--json", "emit JSON", false)
|
|
34
|
+
.option("--model <id>", "override model for this call")
|
|
35
|
+
.action(ideawriting);
|
|
36
|
+
program
|
|
37
|
+
.command("selfish-explorer")
|
|
38
|
+
.description("[Generate] Selfish Explorer — surface unexpected corpus connections to a half-formed idea")
|
|
39
|
+
.argument("<idea>", "the half-formed idea")
|
|
40
|
+
.option("-n, --n <count>", "number of connections", "3")
|
|
41
|
+
.option("--corpus <path>", "override corpus directory")
|
|
42
|
+
.option("--json", "emit JSON", false)
|
|
43
|
+
.option("--model <id>", "override model for this call")
|
|
44
|
+
.action(selfishExplorer);
|
|
45
|
+
// ─── DEVELOP ───────────────────────────────────────────────────────────────
|
|
46
|
+
program
|
|
47
|
+
.command("paper-house")
|
|
48
|
+
.description("[Develop] Paper House Checker — refuse critique until an idea fits on a sticky note")
|
|
49
|
+
.argument("<file-or-text>", "path to a file, or the idea as a quoted string")
|
|
50
|
+
.option("--max-words <count>", "word budget", "80")
|
|
51
|
+
.option("--json", "emit JSON", false)
|
|
52
|
+
.action(paperHouse);
|
|
53
|
+
program
|
|
54
|
+
.command("delphi")
|
|
55
|
+
.description("[Develop] Delphi Rounds — iterative anonymous synthetic-expert rounds")
|
|
56
|
+
.argument("<claim>", "the claim under review")
|
|
57
|
+
.option("-r, --rounds <count>", "Delphi iterations", "2")
|
|
58
|
+
.option("--corpus <path>", "override corpus directory")
|
|
59
|
+
.option("--json", "emit JSON", false)
|
|
60
|
+
.option("--model <id>", "override model for this call")
|
|
61
|
+
.action(delphi);
|
|
62
|
+
// ─── SELECT ────────────────────────────────────────────────────────────────
|
|
63
|
+
program
|
|
64
|
+
.command("discovery-actionability")
|
|
65
|
+
.description("[Select] Discovery × Actionability — plot candidate ideas on Chris's 2×2")
|
|
66
|
+
.argument("<ideas>", 'one or more ideas, separated by ";"')
|
|
67
|
+
.option("--corpus <path>", "override corpus directory")
|
|
68
|
+
.option("--json", "emit JSON", false)
|
|
69
|
+
.option("--model <id>", "override model for this call")
|
|
70
|
+
.action(discoveryActionability);
|
|
71
|
+
// ─── PROMOTE ───────────────────────────────────────────────────────────────
|
|
72
|
+
program
|
|
73
|
+
.command("easy-on-people")
|
|
74
|
+
.description("[Promote] Easy-on-People Framer — rewrite critique to separate act from person")
|
|
75
|
+
.argument("<critique>", "the blunt critique")
|
|
76
|
+
.option("--tone <tone>", "gentle | direct", "direct")
|
|
77
|
+
.option("--json", "emit JSON", false)
|
|
78
|
+
.option("--model <id>", "override model for this call")
|
|
79
|
+
.action(easyOnPeople);
|
|
80
|
+
program
|
|
81
|
+
.command("between-sessions")
|
|
82
|
+
.description("[Promote] Between Sessions Companion — draft a class opener from recent session notes")
|
|
83
|
+
.option("--date <date>", "target session date (YYYY-MM-DD)")
|
|
84
|
+
.option("--sessions-dir <path>", "override sessions directory", "./sessions")
|
|
85
|
+
.option("--json", "emit JSON", false)
|
|
86
|
+
.option("--model <id>", "override model for this call")
|
|
87
|
+
.action(betweenSessions);
|
|
88
|
+
// ─── CONFIG ────────────────────────────────────────────────────────────────
|
|
89
|
+
program
|
|
90
|
+
.command("config")
|
|
91
|
+
.description("Manage big-tools configuration (API keys, default model)")
|
|
92
|
+
.argument("<action>", "get | set | list")
|
|
93
|
+
.argument("[key]", "config key")
|
|
94
|
+
.argument("[value]", "config value")
|
|
95
|
+
.action(config);
|
|
96
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
97
|
+
console.error(`\nError: ${err instanceof Error ? err.message : String(err)}`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function betweenSessions(opts) {
|
|
2
|
+
// TODO: port from .claude/commands/between-sessions.md
|
|
3
|
+
// - discover newest session note in opts.sessionsDir
|
|
4
|
+
// - extract Parking Lot items, held-back content, unresolved threads
|
|
5
|
+
// - draft 4-6 sentence opener in Carl's register
|
|
6
|
+
// - run style-audit (6 checks) and refuse to emit failing draft
|
|
7
|
+
console.log(`[between-sessions] not yet implemented — sessionsDir=${opts.sessionsDir} date=${opts.date ?? "next"}`);
|
|
8
|
+
process.exit(2);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=between-sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"between-sessions.js","sourceRoot":"","sources":["../../src/commands/between-sessions.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAA4B;IAChE,uDAAuD;IACvD,qDAAqD;IACrD,qEAAqE;IACrE,iDAAiD;IACjD,gEAAgE;IAChE,OAAO,CAAC,GAAG,CACT,wDAAwD,IAAI,CAAC,WAAW,SAAS,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE,CACvG,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readConfig, writeConfig } from "../lib/config-store.js";
|
|
2
|
+
const SENSITIVE_KEYS = new Set(["openrouter-key"]);
|
|
3
|
+
function mask(value) {
|
|
4
|
+
if (value.length <= 4)
|
|
5
|
+
return "****";
|
|
6
|
+
return "****" + value.slice(-4);
|
|
7
|
+
}
|
|
8
|
+
export async function config(action, key, value) {
|
|
9
|
+
switch (action) {
|
|
10
|
+
case "list": {
|
|
11
|
+
const data = readConfig();
|
|
12
|
+
const entries = Object.entries(data).filter((e) => e[1] !== undefined);
|
|
13
|
+
if (entries.length === 0) {
|
|
14
|
+
process.stderr.write("No configuration set.\n");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
for (const [k, v] of entries) {
|
|
18
|
+
console.log(`${k} = ${v}`);
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
case "get": {
|
|
23
|
+
if (!key) {
|
|
24
|
+
process.stderr.write("Usage: big-tools config get <key>\n");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const data = readConfig();
|
|
28
|
+
const val = data[key];
|
|
29
|
+
if (val === undefined) {
|
|
30
|
+
process.stderr.write(`Key '${key}' not set.\n`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
console.log(val);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
case "set": {
|
|
37
|
+
if (!key || value === undefined) {
|
|
38
|
+
process.stderr.write("Usage: big-tools config set <key> <value>\n");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
writeConfig(key, value);
|
|
42
|
+
const display = SENSITIVE_KEYS.has(key) ? mask(value) : value;
|
|
43
|
+
process.stderr.write(`Set ${key} = ${display}\n`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
default:
|
|
47
|
+
process.stderr.write(`Unknown action '${action}'. Usage:\n` +
|
|
48
|
+
` big-tools config list\n` +
|
|
49
|
+
` big-tools config get <key>\n` +
|
|
50
|
+
` big-tools config set <key> <value>\n`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAEnD,SAAS,IAAI,CAAC,KAAa;IACzB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACrC,OAAO,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,GAAY,EAAE,KAAc;IACvE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CACzC,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CACjD,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;YACD,OAAO;QACT,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,GAAG,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC9D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QAED;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,MAAM,aAAa;gBACpC,2BAA2B;gBAC3B,gCAAgC;gBAChC,wCAAwC,CAC3C,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function delphi(claim, opts) {
|
|
2
|
+
// TODO: port from .claude/commands/delphi-rounds.md
|
|
3
|
+
// - 5 synthetic reviewers per round (reviewer 1/2, scope reviewer, literature reviewer, panel chair)
|
|
4
|
+
// - iterate for N rounds, carrying chair's synthesis forward
|
|
5
|
+
// - emit artifact to ./tribunal-YYYY-MM-DD-slug.json
|
|
6
|
+
const rounds = Math.max(1, Math.min(5, parseInt(opts.rounds, 10) || 2));
|
|
7
|
+
console.log(`[delphi] not yet implemented — claim="${claim.slice(0, 60)}..." rounds=${rounds}`);
|
|
8
|
+
process.exit(2);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=delphi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delphi.js","sourceRoot":"","sources":["../../src/commands/delphi.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAa,EAAE,IAAmB;IAC7D,oDAAoD;IACpD,qGAAqG;IACrG,6DAA6D;IAC7D,qDAAqD;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,CAAC,yCAAyC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;IAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export async function discoveryActionability(ideas, _opts) {
|
|
2
|
+
// TODO: port from .claude/commands/discovery-actionability.md
|
|
3
|
+
// - split ideas on ";"
|
|
4
|
+
// - score each on Discovery Value (0-10) and Actionability (0-10) using corpus evidence
|
|
5
|
+
// - render text-mode 2x2 plot
|
|
6
|
+
// - cite at least one corpus source per axis per idea
|
|
7
|
+
// - print portfolio questions, NOT rankings
|
|
8
|
+
const parsed = ideas
|
|
9
|
+
.split(";")
|
|
10
|
+
.map((s) => s.trim())
|
|
11
|
+
.filter(Boolean);
|
|
12
|
+
console.log(`[discovery-actionability] not yet implemented — ${parsed.length} ideas`);
|
|
13
|
+
process.exit(2);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=discovery-actionability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery-actionability.js","sourceRoot":"","sources":["../../src/commands/discovery-actionability.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAa,EACb,KAAoC;IAEpC,8DAA8D;IAC9D,uBAAuB;IACvB,wFAAwF;IACxF,8BAA8B;IAC9B,sDAAsD;IACtD,4CAA4C;IAC5C,MAAM,MAAM,GAAG,KAAK;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,mDAAmD,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC;IACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export async function easyOnPeople(critique, opts) {
|
|
2
|
+
// TODO: small model call with a Carl-vocabulary reframe template
|
|
3
|
+
// - separate act from person
|
|
4
|
+
// - preserve semantic content of the critique
|
|
5
|
+
// - tone: gentle | direct (both are hard on ideas)
|
|
6
|
+
console.log(`[easy-on-people] not yet implemented — tone=${opts.tone} critique="${critique.slice(0, 60)}..."`);
|
|
7
|
+
process.exit(2);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=easy-on-people.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easy-on-people.js","sourceRoot":"","sources":["../../src/commands/easy-on-people.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,IAAyB;IAC5E,iEAAiE;IACjE,6BAA6B;IAC7B,8CAA8C;IAC9C,mDAAmD;IACnD,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,IAAI,cAAc,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC/G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export async function ideawriting(prompt, opts) {
|
|
2
|
+
// TODO: port Ideawriting pattern — silent written brainstorm across N model calls
|
|
3
|
+
const n = Math.max(3, Math.min(9, parseInt(opts.n, 10) || 5));
|
|
4
|
+
console.log(`[ideawriting] not yet implemented — prompt="${prompt.slice(0, 60)}..." n=${n}`);
|
|
5
|
+
process.exit(2);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=ideawriting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ideawriting.js","sourceRoot":"","sources":["../../src/commands/ideawriting.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,IAAwB;IACxE,kFAAkF;IAClF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,+CAA+C,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { resolveProvider } from "../lib/resolve-provider.js";
|
|
2
|
+
import { runQueue } from "../lib/queue.js";
|
|
3
|
+
import { print } from "../lib/format.js";
|
|
4
|
+
const SYSTEM_PROMPT = "You are one voice in a Nominal Group Technique session. " +
|
|
5
|
+
"Generate your own response to the brief independently. " +
|
|
6
|
+
"Do not reference other participants or attempt to rank ideas. " +
|
|
7
|
+
"Be specific and concrete. Keep your response under 200 words.";
|
|
8
|
+
export async function ngt(prompt, opts) {
|
|
9
|
+
const n = Math.max(3, Math.min(9, parseInt(opts.n, 10) || 5));
|
|
10
|
+
const provider = resolveProvider({ model: opts.model });
|
|
11
|
+
const tasks = [];
|
|
12
|
+
for (let i = 0; i < n; i++) {
|
|
13
|
+
tasks.push(() => provider.complete(prompt, {
|
|
14
|
+
systemPrompt: SYSTEM_PROMPT,
|
|
15
|
+
temperature: 0.9,
|
|
16
|
+
maxTokens: 400,
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
const onProgress = (current, total) => {
|
|
20
|
+
if (!opts.json) {
|
|
21
|
+
process.stderr.write(`Generating response ${current} of ${total}...\n`);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const responses = await runQueue(tasks, {
|
|
25
|
+
parallel: opts.parallel,
|
|
26
|
+
onProgress,
|
|
27
|
+
});
|
|
28
|
+
const labels = responses.map((_, i) => String.fromCharCode(65 + i));
|
|
29
|
+
const formatted = responses
|
|
30
|
+
.map((text, i) => `[${labels[i]}]\n${text.trim()}`)
|
|
31
|
+
.join("\n\n");
|
|
32
|
+
const result = {
|
|
33
|
+
ok: true,
|
|
34
|
+
phase: "generate",
|
|
35
|
+
tool: "ngt",
|
|
36
|
+
output: formatted,
|
|
37
|
+
data: {
|
|
38
|
+
prompt,
|
|
39
|
+
n,
|
|
40
|
+
model: provider.defaultModel,
|
|
41
|
+
responses: responses.map((text, i) => ({
|
|
42
|
+
label: labels[i],
|
|
43
|
+
text: text.trim(),
|
|
44
|
+
})),
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
print(result, opts.json);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=ngt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngt.js","sourceRoot":"","sources":["../../src/commands/ngt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQzC,MAAM,aAAa,GACjB,0DAA0D;IAC1D,yDAAyD;IACzD,gEAAgE;IAChE,+DAA+D,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,MAAc,EAAE,IAAgB;IACxD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAExD,MAAM,KAAK,GAAiC,EAAE,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CACd,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE;YACxB,YAAY,EAAE,aAAa;YAC3B,WAAW,EAAE,GAAG;YAChB,SAAS,EAAE,GAAG;SACf,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,KAAa,EAAE,EAAE;QACpD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE;QACtC,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,SAAS;SACxB,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;SAClD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAkB;QAC5B,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE;YACJ,MAAM;YACN,CAAC;YACD,KAAK,EAAE,QAAQ,CAAC,YAAY;YAC5B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;gBAChB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aAClB,CAAC,CAAC;SACJ;KACF,CAAC;IAEF,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { print } from "../lib/format.js";
|
|
3
|
+
export async function paperHouse(fileOrText, opts) {
|
|
4
|
+
const maxWords = parseInt(opts.maxWords, 10) || 80;
|
|
5
|
+
const content = existsSync(fileOrText) ? readFileSync(fileOrText, "utf-8") : fileOrText;
|
|
6
|
+
const trimmed = content.trim();
|
|
7
|
+
const diagnostics = [];
|
|
8
|
+
// Check 1: word count
|
|
9
|
+
const words = trimmed.split(/\s+/).filter(Boolean);
|
|
10
|
+
const wordCount = words.length;
|
|
11
|
+
const wordBudget = wordCount <= maxWords;
|
|
12
|
+
if (!wordBudget) {
|
|
13
|
+
diagnostics.push(`${wordCount} words exceeds the ${maxWords}-word budget.`);
|
|
14
|
+
}
|
|
15
|
+
// Check 2: single paragraph (no double newlines)
|
|
16
|
+
const paragraphs = trimmed.split(/\n\n+/).filter((s) => s.trim().length > 0);
|
|
17
|
+
const singleParagraph = paragraphs.length <= 1;
|
|
18
|
+
if (!singleParagraph) {
|
|
19
|
+
diagnostics.push(`${paragraphs.length} paragraphs detected. A sticky note has one paragraph.`);
|
|
20
|
+
}
|
|
21
|
+
// Check 3: no markdown headings
|
|
22
|
+
const noHeadings = !/^#{1,6}\s/m.test(trimmed);
|
|
23
|
+
if (!noHeadings) {
|
|
24
|
+
diagnostics.push("Markdown headings detected. A sticky note is plain text.");
|
|
25
|
+
}
|
|
26
|
+
const pass = wordBudget && singleParagraph && noHeadings;
|
|
27
|
+
const result = {
|
|
28
|
+
ok: pass,
|
|
29
|
+
phase: "develop",
|
|
30
|
+
tool: "paper-house",
|
|
31
|
+
output: pass
|
|
32
|
+
? `PASS (${wordCount}/${maxWords} words)`
|
|
33
|
+
: `FAIL (${wordCount}/${maxWords} words)\n${diagnostics.join("\n")}`,
|
|
34
|
+
data: {
|
|
35
|
+
wordCount,
|
|
36
|
+
maxWords,
|
|
37
|
+
checks: { wordBudget, singleParagraph, noHeadings },
|
|
38
|
+
diagnostics,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
print(result, opts.json);
|
|
42
|
+
process.exit(pass ? 0 : 1);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=paper-house.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paper-house.js","sourceRoot":"","sources":["../../src/commands/paper-house.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAOzC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB,EAAE,IAAuB;IAC1E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IACnD,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACxF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAE/B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,sBAAsB;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/B,MAAM,UAAU,GAAG,SAAS,IAAI,QAAQ,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,sBAAsB,QAAQ,eAAe,CAAC,CAAC;IAC9E,CAAC;IAED,iDAAiD;IACjD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7E,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,WAAW,CAAC,IAAI,CACd,GAAG,UAAU,CAAC,MAAM,wDAAwD,CAC7E,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,IAAI,eAAe,IAAI,UAAU,CAAC;IAEzD,MAAM,MAAM,GAAkB;QAC5B,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,IAAI;YACV,CAAC,CAAC,SAAS,SAAS,IAAI,QAAQ,SAAS;YACzC,CAAC,CAAC,SAAS,SAAS,IAAI,QAAQ,YAAY,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACtE,IAAI,EAAE;YACJ,SAAS;YACT,QAAQ;YACR,MAAM,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE;YACnD,WAAW;SACZ;KACF,CAAC;IAEF,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export async function selfishExplorer(idea, opts) {
|
|
2
|
+
// TODO: port from .claude/commands/ngt-round-robin.md exit ramp + devlex-concept pattern
|
|
3
|
+
// - corpus search for unexpected connections (not just keyword-adjacent)
|
|
4
|
+
// - surface N (default 3) with short "why unexpected" rationales
|
|
5
|
+
const n = Math.max(1, Math.min(9, parseInt(opts.n, 10) || 3));
|
|
6
|
+
console.log(`[selfish-explorer] not yet implemented — idea="${idea.slice(0, 60)}..." n=${n}`);
|
|
7
|
+
process.exit(2);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=selfish-explorer.js.map
|