@anhvupt/tito 0.1.0 → 0.1.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/README.md +11 -4
- package/dist/cli.js +18 -8
- package/dist/core/init.js +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,10 +84,17 @@ npx tito init --profile client-careful
|
|
|
84
84
|
npx tito init --profile client-careful --confirm
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
The first `init` prints the plan and writes nothing.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
The first `init` prints the plan and writes nothing. In a terminal, omitting
|
|
88
|
+
`--profile` asks you to choose `client-careful`, `solo-balanced`, or
|
|
89
|
+
`solo-fast`. A script or piped command must still pass `--profile`.
|
|
90
|
+
`--confirm` creates the missing Tito files and specialist agents. It keeps an
|
|
91
|
+
existing `AGENTS.md` and refuses to overwrite a file that is already there.
|
|
92
|
+
Open a new Cursor chat, then start with `/tito`.
|
|
93
|
+
|
|
94
|
+
Tito is installed in each project. It is not a required global command, and
|
|
95
|
+
there is no global configuration yet. A future personal default would be
|
|
96
|
+
overridden by that project's `tito.yaml`. The safety floor still cannot be
|
|
97
|
+
weakened.
|
|
91
98
|
|
|
92
99
|
## What works today
|
|
93
100
|
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createInterface } from "node:readline/promises";
|
|
3
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
2
4
|
import { readFileSync } from "node:fs";
|
|
3
5
|
import { parseArgs } from "node:util";
|
|
4
6
|
import { InspectionError, formatInspection, inspectRepository, } from "./core/inspect.js";
|
|
5
7
|
import { PlanError, formatAdoptionPlan, planAdoption } from "./core/plan.js";
|
|
6
|
-
import { InitError, applyInitialization, formatInitialization, planInitialization, } from "./core/init.js";
|
|
8
|
+
import { InitError, applyInitialization, formatInitialization, planInitialization, promptForProfile, } from "./core/init.js";
|
|
7
9
|
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
8
10
|
const help = `Tito — quiet orchestration for solo builders
|
|
9
11
|
|
|
@@ -11,7 +13,7 @@ Usage:
|
|
|
11
13
|
tito [options]
|
|
12
14
|
tito inspect [--root <path>]
|
|
13
15
|
tito apply --dry-run --profile <id> [--root <path>]
|
|
14
|
-
tito init --profile <id> [--root <path>] [--confirm]
|
|
16
|
+
tito init [--profile <id>] [--root <path>] [--confirm]
|
|
15
17
|
|
|
16
18
|
Options:
|
|
17
19
|
-h, --help Show help
|
|
@@ -106,7 +108,7 @@ function runApply(args) {
|
|
|
106
108
|
throw error;
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
|
-
function runInit(args) {
|
|
111
|
+
async function runInit(args) {
|
|
110
112
|
if (args.includes("-h") || args.includes("--help")) {
|
|
111
113
|
process.stdout.write(help);
|
|
112
114
|
return;
|
|
@@ -136,8 +138,17 @@ function runInit(args) {
|
|
|
136
138
|
return;
|
|
137
139
|
}
|
|
138
140
|
if (profile === undefined) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
if (!input.isTTY) {
|
|
142
|
+
fail("Missing required option --profile.");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const prompts = createInterface({ input, output });
|
|
146
|
+
try {
|
|
147
|
+
profile = await promptForProfile((prompt) => prompts.question(prompt));
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
prompts.close();
|
|
151
|
+
}
|
|
141
152
|
}
|
|
142
153
|
try {
|
|
143
154
|
const plan = planInitialization(inspectRepository(root), profile);
|
|
@@ -163,7 +174,7 @@ function runInit(args) {
|
|
|
163
174
|
throw error;
|
|
164
175
|
}
|
|
165
176
|
}
|
|
166
|
-
function run(args) {
|
|
177
|
+
async function run(args) {
|
|
167
178
|
if (args[0] === "inspect") {
|
|
168
179
|
runInspect(args.slice(1));
|
|
169
180
|
return;
|
|
@@ -173,8 +184,7 @@ function run(args) {
|
|
|
173
184
|
return;
|
|
174
185
|
}
|
|
175
186
|
if (args[0] === "init") {
|
|
176
|
-
runInit(args.slice(1));
|
|
177
|
-
return;
|
|
187
|
+
return runInit(args.slice(1));
|
|
178
188
|
}
|
|
179
189
|
let helpRequested = false;
|
|
180
190
|
let versionRequested = false;
|
package/dist/core/init.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { compiledCursorAgents } from "./agents.js";
|
|
4
|
+
import { ACTIVE_RISK_PROFILE_IDS } from "./profiles.js";
|
|
4
5
|
import { PlanError, planAdoption, } from "./plan.js";
|
|
5
6
|
export class InitError extends Error {
|
|
6
7
|
code;
|
|
@@ -10,6 +11,17 @@ export class InitError extends Error {
|
|
|
10
11
|
this.code = "conflict";
|
|
11
12
|
}
|
|
12
13
|
}
|
|
14
|
+
export async function promptForProfile(ask) {
|
|
15
|
+
const choices = ACTIVE_RISK_PROFILE_IDS.map((id, index) => ` ${index + 1}. ${id}`).join("\n");
|
|
16
|
+
const answer = (await ask(`Profiles:\n${choices}\nProfile: `)).trim();
|
|
17
|
+
const index = Number(answer);
|
|
18
|
+
if (Number.isInteger(index) &&
|
|
19
|
+
index >= 1 &&
|
|
20
|
+
index <= ACTIVE_RISK_PROFILE_IDS.length) {
|
|
21
|
+
return ACTIVE_RISK_PROFILE_IDS[index - 1] ?? answer;
|
|
22
|
+
}
|
|
23
|
+
return answer;
|
|
24
|
+
}
|
|
13
25
|
function exists(root, path) {
|
|
14
26
|
try {
|
|
15
27
|
return statSync(join(root, path)).isFile();
|