halfcycle 0.4.13 → 0.4.15
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/.claude-plugin/plugin.json +1 -1
- package/bin/bin.bundle.mjs +6308 -588
- package/bin/pre-tool-use-filter.sh +134 -6
- package/commands/agent-teams-orchestration.md +1 -1
- package/commands/consistency-check.md +1 -1
- package/commands/context-update.md +1 -1
- package/commands/halfcycle-design.md +1 -1
- package/commands/halfcycle-setup.md +1 -1
- package/commands/stack-assembly-worker.md +1 -1
- package/commands/task-execution.md +1 -1
- package/commands/task-graph.md +1 -1
- package/commands/write-spec.md +1 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/build-record/pair-io.d.ts +49 -0
- package/dist/build-record/pair-io.d.ts.map +1 -0
- package/dist/build-record/render-change.d.ts +25 -0
- package/dist/build-record/render-change.d.ts.map +1 -0
- package/dist/build-record/render-v2.d.ts +10 -5
- package/dist/build-record/render-v2.d.ts.map +1 -1
- package/dist/build-record/write-change.d.ts +63 -0
- package/dist/build-record/write-change.d.ts.map +1 -0
- package/dist/build-record/write.d.ts +5 -15
- package/dist/build-record/write.d.ts.map +1 -1
- package/dist/change.d.ts +136 -0
- package/dist/change.d.ts.map +1 -0
- package/dist/check-tasks.d.ts +71 -0
- package/dist/check-tasks.d.ts.map +1 -0
- package/dist/claude-plan.d.ts +133 -0
- package/dist/claude-plan.d.ts.map +1 -0
- package/dist/cli-contract.d.ts +12 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +9670 -4933
- package/dist/cli.js.map +3 -3
- package/dist/close-phase.d.ts +53 -1
- package/dist/close-phase.d.ts.map +1 -1
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/folder-refusals.d.ts +27 -0
- package/dist/folder-refusals.d.ts.map +1 -0
- package/dist/identity.d.ts +31 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/index.js +2832 -1324
- package/dist/index.js.map +3 -3
- package/dist/install-manifest.d.ts +11 -1
- package/dist/install-manifest.d.ts.map +1 -1
- package/dist/install-plan.d.ts +112 -0
- package/dist/install-plan.d.ts.map +1 -0
- package/dist/install.d.ts +593 -2
- package/dist/install.d.ts.map +1 -1
- package/dist/merge-settings.d.ts +21 -2
- package/dist/merge-settings.d.ts.map +1 -1
- package/dist/open-phase.d.ts +1 -1
- package/dist/open-phase.d.ts.map +1 -1
- package/dist/pace.d.ts +138 -0
- package/dist/pace.d.ts.map +1 -0
- package/dist/phase-work.d.ts +37 -0
- package/dist/phase-work.d.ts.map +1 -0
- package/dist/plan.d.ts +20 -4
- package/dist/plan.d.ts.map +1 -1
- package/dist/pre-create-checks.d.ts +28 -0
- package/dist/pre-create-checks.d.ts.map +1 -1
- package/dist/preview.d.ts +40 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/prove.d.ts +77 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/restore.d.ts +58 -0
- package/dist/restore.d.ts.map +1 -0
- package/dist/review.d.ts +19 -1
- package/dist/review.d.ts.map +1 -1
- package/dist/scan.d.ts +11 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/setup/discovery.d.ts.map +1 -1
- package/dist/setup/rows.d.ts +10 -6
- package/dist/setup/rows.d.ts.map +1 -1
- package/dist/system-report.d.ts +1 -1
- package/dist/system-report.d.ts.map +1 -1
- package/dist/uninstall.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/change.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx halfcycle@latest change` — sorting a change, moving it up, and ending a small
|
|
3
|
+
* change (Safe, lean, fast · E3, feature `three-paths` AC2–AC4, AC6's writer, AC8's
|
|
4
|
+
* missing route; `mini-phase` *The CLI*).
|
|
5
|
+
*
|
|
6
|
+
* THREE FORMS, required flags declared once in `cli-contract.ts` (`missingRequirements`
|
|
7
|
+
* enforces them, and the remedy-string seam test reads the same table):
|
|
8
|
+
* - `change sort --request "<line>" --touches <path>… [--contract <from>:<to>]…
|
|
9
|
+
* [--stored-data] [--standing-rule] [--new-part]` checks `docs/system.json` exactly as
|
|
10
|
+
* `system` does (`checkAndReportDescription`, the one path), reads HEAD as the start
|
|
11
|
+
* commit (a project with no commit cannot sort), sends the description, then the
|
|
12
|
+
* sort, and prints control's answer: its sentence, the sorting's id, what to say next.
|
|
13
|
+
* The path is never worked out here: control re-runs the one rule (`sortChange`) and
|
|
14
|
+
* records its own answer. The request is checked locally with the contracts' own
|
|
15
|
+
* `checkChangeSortRequest` first, so a request control would refuse costs no request.
|
|
16
|
+
* - `change up <mini|full> --change <id>` moves an unfinished small change up and, the
|
|
17
|
+
* change now being finished, writes its record pair; `--phase <phase>` moves a mini
|
|
18
|
+
* phase up instead. A move down is refused here with the contracts' own sentence,
|
|
19
|
+
* before anything is sent; control refuses it again, as it refuses every move down.
|
|
20
|
+
* - `change done <id>` reads the record FIRST. A record found means the change has
|
|
21
|
+
* ended: the pair is written, the outcome printed, and nothing else happens — no
|
|
22
|
+
* runner is started, no report is sent. Only when the service says the change has
|
|
23
|
+
* not ended does it start the runner's `observe --change <id>`, which reads the
|
|
24
|
+
* basis, counts or finishes by the work standing, and prints one line this module
|
|
25
|
+
* parses with `observeChangeRunResultSchema` (one home, shared with the runner).
|
|
26
|
+
*
|
|
27
|
+
* THE RECORD'S FILENAME COMES FROM THE `<id>` ARGUMENT, checked as a change id here and
|
|
28
|
+
* again by the writer, never from a field of the record (INV-023).
|
|
29
|
+
*
|
|
30
|
+
* A SMALL CHANGE IS NOT A PHASE (INV-024): no line here asks for, mentions or marks an
|
|
31
|
+
* approval. Every sentence about a path is the contracts' `CHANGE_PATH_WORDS` or
|
|
32
|
+
* control's own answer; none is restated here (INV-003). Nothing a step id; the next
|
|
33
|
+
* thing to say is the phrase control's answer carries (INV-016).
|
|
34
|
+
*
|
|
35
|
+
* TOPOLOGY. Every route here takes the project credential alone: no GitHub
|
|
36
|
+
* installation, no open phase, no portal session (INV-022). A service without a route
|
|
37
|
+
* is told apart by `isMissingRoute`, and the CLI says so and exits 1.
|
|
38
|
+
*
|
|
39
|
+
* INV-001: Node builtins, the global `fetch`, `@halfcycle/events` and `@halfcycle/core`
|
|
40
|
+
* only; the runner is spawned, never imported. SHIPS TO CLIENT DISK inside the CLI: no
|
|
41
|
+
* comment sits beside an object member, and every string is a sentence a person reads.
|
|
42
|
+
*/
|
|
43
|
+
import { type ChangeContract, type ObserveChangeRunResult, type SmallChangeRecord } from '@halfcycle/events';
|
|
44
|
+
import { type HeadCommitOutcome } from './close-phase.js';
|
|
45
|
+
import type { RepoCredential } from './open-phase.js';
|
|
46
|
+
import { type SystemDeps, type SystemRun } from './system-report.js';
|
|
47
|
+
import { type ChangeRecordPairResult } from './build-record/write-change.js';
|
|
48
|
+
/** The verb's usage, one home: printed by `--help` and by a usage error. */
|
|
49
|
+
export declare const CHANGE_USAGE: string;
|
|
50
|
+
/** What one invocation asks for, once its words have been read. */
|
|
51
|
+
export type ChangeArgs = {
|
|
52
|
+
readonly form: 'sort';
|
|
53
|
+
readonly request: string;
|
|
54
|
+
readonly touches: readonly string[];
|
|
55
|
+
readonly contracts: readonly ChangeContract[];
|
|
56
|
+
readonly storedData: boolean;
|
|
57
|
+
readonly standingRule: boolean;
|
|
58
|
+
readonly newPart: boolean;
|
|
59
|
+
readonly repoRoot?: string;
|
|
60
|
+
} | {
|
|
61
|
+
readonly form: 'up';
|
|
62
|
+
readonly to: 'mini' | 'full';
|
|
63
|
+
readonly target: {
|
|
64
|
+
readonly kind: 'change';
|
|
65
|
+
readonly sortingId: string;
|
|
66
|
+
} | {
|
|
67
|
+
readonly kind: 'phase';
|
|
68
|
+
readonly phase: string;
|
|
69
|
+
};
|
|
70
|
+
readonly repoRoot?: string;
|
|
71
|
+
} | {
|
|
72
|
+
readonly form: 'done';
|
|
73
|
+
readonly sortingId: string;
|
|
74
|
+
readonly repoRoot?: string;
|
|
75
|
+
};
|
|
76
|
+
/** The words read, or the line to print and the code to exit with. Nothing was sent. */
|
|
77
|
+
export type ParsedChange = {
|
|
78
|
+
ok: true;
|
|
79
|
+
args: ChangeArgs;
|
|
80
|
+
} | {
|
|
81
|
+
ok: false;
|
|
82
|
+
line: string;
|
|
83
|
+
exitCode: 1 | 2;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Read `rest` (the words after `change`). The required flags are the contract's
|
|
87
|
+
* (`missingRequirements`), refused first with the contract's own sentence; then each
|
|
88
|
+
* form's own words are read, and anything else is a usage error. Nothing is read from
|
|
89
|
+
* disk and nothing is sent.
|
|
90
|
+
*/
|
|
91
|
+
export declare function parseChangeArgs(rest: readonly string[]): ParsedChange;
|
|
92
|
+
/** The pieces the verb reaches outside itself through; replaced in tests. */
|
|
93
|
+
export interface ChangeDeps extends SystemDeps {
|
|
94
|
+
readonly readHead: (repoRoot: string) => HeadCommitOutcome;
|
|
95
|
+
readonly fetch: typeof fetch;
|
|
96
|
+
readonly observeChange: (credential: RepoCredential, repoRoot: string, sortingId: string) => Promise<ObserveChangeRunResult>;
|
|
97
|
+
readonly writePair: (repoRoot: string, sortingId: string, rawRecord: unknown, record: SmallChangeRecord) => ChangeRecordPairResult;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The one line the `observe --change` child printed, read through the shared
|
|
101
|
+
* `observeChangeRunResultSchema`, or `unreachable` when stdout holds no such line.
|
|
102
|
+
*/
|
|
103
|
+
export declare function readObserveChangeLine(stdout: string): ObserveChangeRunResult;
|
|
104
|
+
/**
|
|
105
|
+
* End a small change through the runner's `observe --change <id>`, spawned the way the
|
|
106
|
+
* close step spawns the runner's verbs (`runRunnerChild`), with the same credential.
|
|
107
|
+
* The id is the checked argument. Never throws.
|
|
108
|
+
*/
|
|
109
|
+
export declare function runObserveChangeChild(binary: string | Error, credential: RepoCredential, repoRoot: string, sortingId: string): Promise<ObserveChangeRunResult>;
|
|
110
|
+
/** The line naming what to say next: the phrase the service's answer carries. */
|
|
111
|
+
export declare function nextSayLine(say: string): string;
|
|
112
|
+
/** The command that ends a small change, or writes its record again: the one remedy. */
|
|
113
|
+
export declare function changeDoneCommand(sortingId: string): string;
|
|
114
|
+
/** What a finished change's record says about how it ended, in the contracts' words. */
|
|
115
|
+
export declare function recordOutcomeLines(record: SmallChangeRecord): string;
|
|
116
|
+
/**
|
|
117
|
+
* `change sort`. The local check runs with the description that just passed and the
|
|
118
|
+
* HEAD just read; the description version is not known until the service answers, so
|
|
119
|
+
* the local check is given the lowest version there is, which no rule reads beyond its
|
|
120
|
+
* shape. The request that leaves carries the version the service gave.
|
|
121
|
+
*/
|
|
122
|
+
export declare function runChangeSort(repoRoot: string, args: Extract<ChangeArgs, {
|
|
123
|
+
form: 'sort';
|
|
124
|
+
}>, deps: ChangeDeps): Promise<SystemRun>;
|
|
125
|
+
/** `change up`: a small change by its id, or a mini phase by its name. */
|
|
126
|
+
export declare function runChangeUp(repoRoot: string, args: Extract<ChangeArgs, {
|
|
127
|
+
form: 'up';
|
|
128
|
+
}>, deps: ChangeDeps): Promise<SystemRun>;
|
|
129
|
+
/**
|
|
130
|
+
* `change done <id>`. The record is read first; the runner is started only when the
|
|
131
|
+
* service says the change has not ended (three-paths AC4).
|
|
132
|
+
*/
|
|
133
|
+
export declare function runChangeDone(repoRoot: string, sortingId: string, deps: ChangeDeps): Promise<SystemRun>;
|
|
134
|
+
/** The whole verb, once its words are read: the form's run. */
|
|
135
|
+
export declare function runChange(repoRoot: string, args: ChangeArgs, deps: ChangeDeps): Promise<SystemRun>;
|
|
136
|
+
//# sourceMappingURL=change.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../src/change.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `npx halfcycle@latest check-tasks <phase> [--with-task-list] [--repo <root>]`
|
|
3
|
+
* (`collision-free-parallel-work` AC3; `checks-as-work-lands` AC3, AC6).
|
|
4
|
+
*
|
|
5
|
+
* OFFLINE, ALWAYS. This verb reads at most two files on the person's own machine —
|
|
6
|
+
* `docs/build-records/task-plan.json` and, with `--with-task-list`,
|
|
7
|
+
* `docs/build-records/build-tasks.json` — and nothing else. It opens no credential
|
|
8
|
+
* file, makes no network call, and needs no sign-in. Everything it prints comes from
|
|
9
|
+
* `checkTaskPlan` (`@halfcycle/core`), which is pure: this module's whole job is
|
|
10
|
+
* reading the two files, handing them to that function, and printing what it
|
|
11
|
+
* returns.
|
|
12
|
+
*
|
|
13
|
+
* ONE HOME FOR THE PLAN'S SHAPE AND ITS RULES (INV-003): `taskPlanSchema`,
|
|
14
|
+
* `taskListFileSchema`, `checkTaskPlan` and every line it prints live in
|
|
15
|
+
* `@halfcycle/core`'s `task-plan.ts`. This file restates none of them — it only
|
|
16
|
+
* turns a missing or unparsable file into the one kind of answer this verb gives for
|
|
17
|
+
* that (exit 2, naming the file), and turns the function's lines into the exit code
|
|
18
|
+
* the spec pins (0 clean, 1 any refusal).
|
|
19
|
+
*
|
|
20
|
+
* THE TASK LIST IS READ ONLY WHEN ASKED. Without `--with-task-list` this verb never
|
|
21
|
+
* opens `build-tasks.json`, so a stale or disagreeing list on disk from an earlier
|
|
22
|
+
* phase changes nothing about a planning run — the one case
|
|
23
|
+
* `collision-free-parallel-work`'s *Decisions taken* exists to prevent.
|
|
24
|
+
*
|
|
25
|
+
* A MISSING TASK LIST IS NOT AN ERROR. Only the plan file is required input; a task
|
|
26
|
+
* list that is missing, names another phase, or carries no phase at all (the shape
|
|
27
|
+
* written before this release) reads as `checkTaskPlan`'s note N1 and exits 0 on an
|
|
28
|
+
* otherwise clean plan. A plan file in the same state is always a hard failure (exit
|
|
29
|
+
* 2), because the plan is this verb's one required input.
|
|
30
|
+
*
|
|
31
|
+
* SHIPS TO CLIENT DISK inside the CLI (INV-001: Node builtins, `@halfcycle/core`
|
|
32
|
+
* only — no network, so no `@halfcycle/events` and no `fetch`). Every string here is
|
|
33
|
+
* a sentence a person reads in their own terminal, so none names an internal
|
|
34
|
+
* register, a route, or this project's own tooling; no comment sits beside an
|
|
35
|
+
* object member.
|
|
36
|
+
*/
|
|
37
|
+
/** The usage line, printed for no phase, an extra argument or an unknown flag. */
|
|
38
|
+
export declare const CHECK_TASKS_USAGE = "npx halfcycle@latest check-tasks <phase> [--with-task-list] [--repo <root>]";
|
|
39
|
+
/**
|
|
40
|
+
* What the arguments after `check-tasks` came to. Exactly one positional (the
|
|
41
|
+
* phase), at most one `--with-task-list` and at most one `--repo <root>`; anything
|
|
42
|
+
* else, no phase included, is usage.
|
|
43
|
+
*/
|
|
44
|
+
export type CheckTasksArgs = {
|
|
45
|
+
ok: true;
|
|
46
|
+
phase: string;
|
|
47
|
+
withTaskList: boolean;
|
|
48
|
+
repoRoot: string | undefined;
|
|
49
|
+
} | {
|
|
50
|
+
ok: false;
|
|
51
|
+
};
|
|
52
|
+
export declare function parseCheckTasksArgs(argv: readonly string[]): CheckTasksArgs;
|
|
53
|
+
/** What a run of the verb came to. */
|
|
54
|
+
export interface CheckTasksRun {
|
|
55
|
+
readonly stdout: string;
|
|
56
|
+
readonly stderr: string;
|
|
57
|
+
readonly exitCode: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The whole verb. Reads `docs/build-records/task-plan.json` under `repoRoot`, and,
|
|
61
|
+
* with `withTaskList`, `docs/build-records/build-tasks.json`; hands both to
|
|
62
|
+
* `checkTaskPlan` and prints its lines, one per line, in the order it returns them,
|
|
63
|
+
* or `checkTaskPlan`'s own clear line when there is nothing to report. Never throws.
|
|
64
|
+
*
|
|
65
|
+
* Exit 0 when nothing refuses, 1 when anything does, 2 when the plan file is
|
|
66
|
+
* missing or either file cannot be read or parsed as JSON or does not match the
|
|
67
|
+
* shape this tool reads (naming which file, and where). A missing task list is not
|
|
68
|
+
* an error (see the module header) and never changes the exit code on its own.
|
|
69
|
+
*/
|
|
70
|
+
export declare function runCheckTasks(repoRoot: string, phase: string, withTaskList: boolean): CheckTasksRun;
|
|
71
|
+
//# sourceMappingURL=check-tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-tasks.d.ts","sourceRoot":"","sources":["../src/check-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAgBH,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,gFAAgF,CAAC;AAE/G;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAChF;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAElB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,CAuB3E;AA2CD,sCAAsC;AACtC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,aAAa,CA4BnG"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SETUP ASKS THE CLAUDE PLAN ONCE (`builds-paced-to-plan` AC2, setup half).
|
|
3
|
+
*
|
|
4
|
+
* `bin.ts`'s setup arm calls `setupClaudePlan` after the project is created or found.
|
|
5
|
+
* In order:
|
|
6
|
+
*
|
|
7
|
+
* 1. NOBODY IS ASKED, AND NOTHING IS SENT, unless this account owns the project
|
|
8
|
+
* and a person is there (`isInteractiveRun`: a terminal on standard input and no
|
|
9
|
+
* `CI`). That one gate covers a script, CI, an agent running `npx halfcycle` from
|
|
10
|
+
* its own shell (no terminal on standard input) and a guest. A remembered answer
|
|
11
|
+
* is not sent either: the spec's "a setup with no person there sends nothing".
|
|
12
|
+
* 2. A COMPUTER THAT WAS TOLD BEFORE is not asked again: the remembered plan is
|
|
13
|
+
* sent, and, once control has taken it, the remembered line says so. THIS STEP
|
|
14
|
+
* IS NOT GATED ON `--yes` (below) — a bounded network call with a timeout cannot
|
|
15
|
+
* wait forever on anybody, so there is nothing for `--yes` to protect against
|
|
16
|
+
* here, and a `--yes` run genuinely at a real terminal still wants its
|
|
17
|
+
* already-known plan kept in sync silently.
|
|
18
|
+
* 3. OTHERWISE THE QUESTION IS ASKED (`askLine`) — UNLESS `--yes` WAS GIVEN, in
|
|
19
|
+
* which case this step is skipped the same way "no person there" is (W-09 O-W9:
|
|
20
|
+
* a console can be attached with nobody at it — a Windows run started with no
|
|
21
|
+
* interactive session still measured a TTY — so `--yes` is read here the same
|
|
22
|
+
* way `confirmActingIdentity` already reads it, before the TTY is trusted, as
|
|
23
|
+
* the stronger, explicit signal that nobody is going to answer). Otherwise: the
|
|
24
|
+
* answer is remembered on this computer and sent. An answer that names no plan
|
|
25
|
+
* is asked again, up to `PLAN_QUESTION_TRIES` times in all; after that nothing is
|
|
26
|
+
* remembered or sent, and the plan stays unknown until the owner sets it in the
|
|
27
|
+
* console.
|
|
28
|
+
*
|
|
29
|
+
* ONE HOME FOR EVERY WORD AND SHAPE, AND IT IS NOT HERE. The question, the answer's
|
|
30
|
+
* reading, the remembered line, the seven plans and the request body are
|
|
31
|
+
* `@halfcycle/events`' `pacing.ts`; the remembered file's shape IS the request body
|
|
32
|
+
* (`claudePlanRequestSchema`), so the file and the wire cannot drift apart. This
|
|
33
|
+
* module holds only the order above and the file and network I/O.
|
|
34
|
+
*
|
|
35
|
+
* THE CREDENTIAL IS THE MACHINE'S ACCOUNT CREDENTIAL, read the way the create route's
|
|
36
|
+
* is (`HALFCYCLE_TOKEN` in the environment first, else this machine's saved sign-in),
|
|
37
|
+
* and never a browser sign-in: the project is already set up, and a sign-in for a
|
|
38
|
+
* question about pacing would be out of all proportion. The engagement credential is
|
|
39
|
+
* never sent; control refuses it on this route. With no account credential the answer
|
|
40
|
+
* is still remembered, so the next setup sends it.
|
|
41
|
+
*
|
|
42
|
+
* BEST EFFORT, NEVER A FAILURE. The install has already succeeded when this runs. A
|
|
43
|
+
* network error, a timeout, a refusal (control not yet carrying the route, or a
|
|
44
|
+
* project this account does not own after all) or a file that cannot be written is
|
|
45
|
+
* silent: the remembered answer is re-sent by the next setup, and the owner can set
|
|
46
|
+
* the plan in the console. Nothing here throws.
|
|
47
|
+
*
|
|
48
|
+
* A REMEMBERED ANSWER IS RE-SENT ON EVERY LATER SETUP, as the spec says, so a plan the
|
|
49
|
+
* owner changed in the console is set back by their next `npx halfcycle` on this
|
|
50
|
+
* computer. That is the spec's rule, written down here so it is not mistaken for a
|
|
51
|
+
* defect of this module.
|
|
52
|
+
*
|
|
53
|
+
* INV-001: Node builtins, `@halfcycle/core`, `@halfcycle/events` and this package's
|
|
54
|
+
* own modules. Nothing about usage crosses (ADR-015): only the plan's id.
|
|
55
|
+
*/
|
|
56
|
+
import { type ClaudePlanId } from '@halfcycle/events';
|
|
57
|
+
/** The remembered answer's file name, under `~/.halfcycle/`. Machine-level, never in a project (INV-016). */
|
|
58
|
+
export declare const CLAUDE_PLAN_FILENAME = "claude-plan.json";
|
|
59
|
+
/** How many times the question is put before an answer that names no plan is given up on. */
|
|
60
|
+
export declare const PLAN_QUESTION_TRIES = 3;
|
|
61
|
+
/** `~/.halfcycle/claude-plan.json`. */
|
|
62
|
+
export declare function claudePlanPath(home?: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* The plan this computer was told before, or `undefined` when it was never told or
|
|
65
|
+
* the file does not read as one: a file that does not parse is asked about again and
|
|
66
|
+
* overwritten, never an error.
|
|
67
|
+
*/
|
|
68
|
+
export declare function readRememberedClaudePlan(home?: string): ClaudePlanId | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Remember the plan on this computer, owner-only, the account store's posture
|
|
71
|
+
* (`account-credential.ts`). Returns false when it could not be written.
|
|
72
|
+
*/
|
|
73
|
+
export declare function rememberClaudePlan(plan: ClaudePlanId, home?: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* The owner's settings page, under the project's console address, or `undefined` when
|
|
76
|
+
* this run has no console address (an older control, or none configured). No address
|
|
77
|
+
* is guessed: `bin.ts` passes the same address it prints as the project's console.
|
|
78
|
+
*/
|
|
79
|
+
export declare function settingsPageUrl(consoleUrl: string | undefined): string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Send the plan to `PUT /engagements/:engagementId/claude-plan` with the account
|
|
82
|
+
* credential. True only when control took it (a 2xx). Never throws.
|
|
83
|
+
*/
|
|
84
|
+
export declare function sendClaudePlan(serviceUrl: string, engagementId: string, credential: string, plan: ClaudePlanId, fetchImpl?: typeof fetch): Promise<boolean>;
|
|
85
|
+
/** What `setupClaudePlan` did, for the caller's tests; `bin.ts` reads none of it. */
|
|
86
|
+
export type ClaudePlanSetupOutcome = {
|
|
87
|
+
readonly kind: 'not-owner';
|
|
88
|
+
} | {
|
|
89
|
+
readonly kind: 'no-person';
|
|
90
|
+
} | {
|
|
91
|
+
readonly kind: 'no-answer';
|
|
92
|
+
} | {
|
|
93
|
+
readonly kind: 'failed';
|
|
94
|
+
} | {
|
|
95
|
+
readonly kind: 'remembered';
|
|
96
|
+
readonly plan: ClaudePlanId;
|
|
97
|
+
readonly sent: boolean;
|
|
98
|
+
} | {
|
|
99
|
+
readonly kind: 'answered';
|
|
100
|
+
readonly plan: ClaudePlanId;
|
|
101
|
+
readonly sent: boolean;
|
|
102
|
+
};
|
|
103
|
+
export interface ClaudePlanSetupInput {
|
|
104
|
+
readonly serviceUrl: string;
|
|
105
|
+
readonly engagementId: string;
|
|
106
|
+
/** True when this run's account owns the project; false for a guest, or when ownership is not known. */
|
|
107
|
+
readonly ownsProject: boolean;
|
|
108
|
+
/** The project's console address this run prints, if any; the settings page is under it. */
|
|
109
|
+
readonly consoleUrl: string | undefined;
|
|
110
|
+
}
|
|
111
|
+
export interface ClaudePlanSetupDeps {
|
|
112
|
+
readonly interactive: () => boolean;
|
|
113
|
+
readonly ask: (question: string) => Promise<string>;
|
|
114
|
+
readonly write: (text: string) => void;
|
|
115
|
+
/**
|
|
116
|
+
* `--yes` on the command line: never ask the question, the same as `interactive()`
|
|
117
|
+
* false for THAT ONE STEP (W-09 O-W9 — a measured TTY is not proof somebody is there
|
|
118
|
+
* to answer it). Does NOT also suppress resending an already-remembered plan — that
|
|
119
|
+
* step is a bounded network call, never a wait on a human, so `--yes` has nothing to
|
|
120
|
+
* protect there and a real terminal that happens to pass `--yes` still wants its
|
|
121
|
+
* known plan kept in sync.
|
|
122
|
+
*/
|
|
123
|
+
readonly assumeYes?: boolean;
|
|
124
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
125
|
+
readonly home?: string;
|
|
126
|
+
readonly fetchImpl?: typeof fetch;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The setup arm's one call: ask the plan once, remember it, send it (module
|
|
130
|
+
* docblock). Never throws; the outcome is for tests.
|
|
131
|
+
*/
|
|
132
|
+
export declare function setupClaudePlan(input: ClaudePlanSetupInput, deps: ClaudePlanSetupDeps): Promise<ClaudePlanSetupOutcome>;
|
|
133
|
+
//# sourceMappingURL=claude-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-plan.d.ts","sourceRoot":"","sources":["../src/claude-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAKH,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAG3B,6GAA6G;AAC7G,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AAEvD,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAQrC,uCAAuC;AACvC,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAOhF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAU7E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGlF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,wGAAwG;IACxG,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AASD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAqCjC"}
|
package/dist/cli-contract.d.ts
CHANGED
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
* home is the failure mode it exists to prevent.
|
|
63
63
|
*/
|
|
64
64
|
/** The verbs the CLI dispatches. Anything else after `halfcycle ` is unknown. */
|
|
65
|
-
export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "uninstall"];
|
|
65
|
+
export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "check-tasks", "uninstall", "change", "pace", "prove", "preview", "doctor", "restore"];
|
|
66
66
|
export type CliVerb = (typeof CLI_VERBS)[number];
|
|
67
67
|
/** A flag every invocation of the verb must carry. */
|
|
68
68
|
export interface RequiredFlag {
|
|
@@ -85,10 +85,21 @@ export interface ConditionalFlag {
|
|
|
85
85
|
readonly takesValue: boolean;
|
|
86
86
|
readonly missingMessage: string;
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* One form of a verb that has several, chosen by the first word after the verb
|
|
90
|
+
* (`change sort`, `change up`, `change done`). Each form declares its own required
|
|
91
|
+
* flags; the verb's own lists stay empty.
|
|
92
|
+
*/
|
|
93
|
+
export interface FormContract {
|
|
94
|
+
readonly form: string;
|
|
95
|
+
readonly required: readonly RequiredFlag[];
|
|
96
|
+
readonly conditional: readonly ConditionalFlag[];
|
|
97
|
+
}
|
|
88
98
|
export interface VerbContract {
|
|
89
99
|
readonly verb: CliVerb;
|
|
90
100
|
readonly required: readonly RequiredFlag[];
|
|
91
101
|
readonly conditional: readonly ConditionalFlag[];
|
|
102
|
+
readonly forms?: readonly FormContract[];
|
|
92
103
|
}
|
|
93
104
|
/** The contract for a verb, or `undefined` when the CLI has no such verb. */
|
|
94
105
|
export declare function contractFor(verb: string): VerbContract | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,6MAA8M,CAAC;AAErO,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAwID,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAyBxF;AAuBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvE;AASD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;CAErB,CAAC;AA0BX;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1F"}
|