@gluecharm-lab/easyspecs-cli 0.0.17 → 0.0.19
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 +6 -6
- package/commands.md +119 -101
- package/dist/main.cjs +257 -393
- package/dist/main.cjs.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,10 +5,10 @@ Headless **EasySpecs** command-line tool: same orchestration ideas as the **Easy
|
|
|
5
5
|
## The three factory-level commands
|
|
6
6
|
|
|
7
7
|
1. **`easyspecs-cli analysis` — create new context**
|
|
8
|
-
Runs the full **Generate Context** factory end to end (synthesis until stable, coverage, remediation, reporting, link mapping, index assembly). Use this when you need a fresh or full rebuild of **`.gluecharm/context`** from the repo.
|
|
8
|
+
Runs the full **Generate Context** factory end to end (synthesis until stable, coverage, remediation, reporting, link mapping, index assembly). Use this when you need a fresh or full rebuild of **`.gluecharm/context`** from the repo. **`--force-new-context-analysis`** overrides skip-when-already-analyzed behavior when **`easyspecs.factory.cloudContextAnalyzed`** would otherwise short-circuit the run. After **`analysis`**, run **`easyspecs-cli upload context`** or **`upload republish`** when you want context on EasySpecs (**`auth login`** + **`config set-project-id`**). If **`git worktree add`** fails because a temp analysis checkout folder was removed but Git still lists it, the CLI runs **`git worktree prune`** in your repository and retries **`git worktree add`** once (same behaviour wherever the CLI creates that temp worktree).
|
|
9
9
|
|
|
10
10
|
2. **`easyspecs-cli update context` — update context from code churn**
|
|
11
|
-
Incremental refresh from a **git delta** since the stored baseline (**`easyspecs.factory.updateContext.lastRunAt`**) or, when that is absent, inferred from workspace context mtimes: materialises **`changes-since-date.md`**, runs **scoped** remediation when commits and touched paths warrant it, then optional promotion
|
|
11
|
+
Incremental refresh from a **git delta** since the stored baseline (**`easyspecs.factory.updateContext.lastRunAt`**) or, when that is absent, inferred from workspace context mtimes: materialises **`changes-since-date.md`**, runs **scoped** remediation when commits and touched paths warrant it, then optional promotion. Use **`upload context`** afterward when you need cloud sync. Use this day to day after **`analysis`** when the codebase moved but specs did not restart from zero.
|
|
12
12
|
|
|
13
13
|
3. **`easyspecs-cli context drift <referencePath>` — analyze drift against specs**
|
|
14
14
|
**`referencePath`** is a **file or directory** of truth documents (requirements, specs, PRD, architecture notes — whatever your team treats as ground truth relative to repo root). The CLI compares **repository / analysis worktree** context against that reference (OpenCode-assisted), writes **`drift-<label>-<date>.md`** under **`.gluecharm/context/drift/`**, and can update the reference index markdown. **`--label <slug>`** names the report file; **`--index <path>`** overrides which root markdown anchors the comparison; **`--dry-run`** validates references only (**no worktree, agent, or writes**).
|
|
@@ -56,7 +56,7 @@ easyspecs-cli config init
|
|
|
56
56
|
easyspecs-cli analysis
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
**`config init`** creates **`.easyspecs/config.json`** with defaults (add **`--overwrite`** to replace an existing file). After the first **`analysis`**, typical follow-ups are **`update context`** (incremental sync with git) and **`context drift`** when you hold truth in specs files/folders elsewhere in the repo. Use **`download context`** (**`auth login`** + **`config set-project-id`**) to pull stored context from EasySpecs into **`.gluecharm/context`**.
|
|
59
|
+
**`config init`** creates **`.easyspecs/config.json`** with defaults (add **`--overwrite`** to replace an existing file). After the first **`analysis`**, typical follow-ups are **`update context`** (incremental sync with git) and **`context drift`** when you hold truth in specs files/folders elsewhere in the repo. Use **`download context`** (**`auth login`** + **`config set-project-id`**) to pull stored context from EasySpecs into **`.gluecharm/context`**. Run **`upload context`** or **`upload republish`** after **`analysis`** / **`update context`** when you want edits on EasySpecs. Use **`--ci`** in automation for non-interactive behaviour and stricter defaults (e.g. Factory outer-iteration cap).
|
|
60
60
|
|
|
61
61
|
Set **`easyspecs.defaultGitRemoteUrl`** with **`config set-git-remote <url>`** when you want that recorded in config. Tunables belong in **`<repo>/.easyspecs/config.json`** — do not rely on **`EASYSPECS_*`** environment variables for product settings.
|
|
62
62
|
|
|
@@ -258,8 +258,8 @@ Every command the CLI accepts, with command-specific tokens. Global flags above
|
|
|
258
258
|
| `run synthesis` | — | Context artefact pipeline pass; **`requireOpenCode`** applies. **`--promote` / `--no-promote`** affect promotion after success. |
|
|
259
259
|
| `run synthesis resume-missing` | **`--worktree <path>`** (optional) | Parallel missing-artefact remediation pool on an existing checkout (from **`--worktree`** or last snapshot). **`requireOpenCode`**. |
|
|
260
260
|
| `run synthesis resume-synthesis` | **`--worktree <path>`** (optional) | Same implementation as **`resume-missing`** (alias command path). |
|
|
261
|
-
| `analysis` | **`--
|
|
262
|
-
| `update context` |
|
|
261
|
+
| `analysis` | **`--force-new-context-analysis`** (optional; tail only). **`--upload`** / **`--skip-upload`** → usage exit; **`--synthesis-only`** → ignored + stderr deprecation (**SRS-60**). | Full **Generate Context** factory — **create new context** trajectory. CLI **does not** run backend upload inside **`analysis`**; use **`upload context`** / **`upload republish`** afterward. If **`easyspecs.factory.cloudContextAnalyzed`** is **`true`** and **`--force-new-context-analysis`** is absent, exits **0** early with **`analysisSkipped`**. Stale temp-worktree registration: **`git worktree prune`** then one retry of **`git worktree add`**. |
|
|
262
|
+
| `update context` | — | **Update context** trajectory: git window after baseline → worktree → **`changes-since-date.md`** → optional remediation → **`--promote` / `--no-promote`** → **`easyspecs.factory.updateContext.lastRunAt`**. Run **`upload context`** separately for cloud sync. Seed context should exist on **HEAD** in the checkout (the factory may copy from workspace when the worktree lacks context). |
|
|
263
263
|
| `diagnose reference-coverage` | **`--root workspace`** \| **`--root worktree`**, optional **`--worktree <path>`** | Reference coverage gate; optional percent limit via **`easyspecs.diagnose.zeroReference.maxPercentNonReferenced`**. |
|
|
264
264
|
| `diagnose coordination-duplicates` | same | Duplicate/orphan reporting; **`easyspecs.diagnose.coordinationDuplicates.strict`**. |
|
|
265
265
|
| `diagnose coverage-report` | same | Writes coverage execution report path. |
|
|
@@ -276,7 +276,7 @@ Every command the CLI accepts, with command-specific tokens. Global flags above
|
|
|
276
276
|
|
|
277
277
|
**OpenCode:** commands that spawn agents require **`opencode`** (or configured executable) on **`PATH`** and credentials unless **`skipCredentialsCheck`** or provider keys in **`config.json`** apply (**`requireOpenCode`**).
|
|
278
278
|
|
|
279
|
-
**EasySpecs API session:** **`download context`**, **`upload context`**, **`upload republish
|
|
279
|
+
**EasySpecs API session:** **`download context`**, **`upload context`**, and **`upload republish`** need a prior **`auth login`** (or **`--ci`** with **`easyspecs.auth.ciLogin`** in **`config.json`** when argv omits email/password on login), plus **`easyspecs.easyspecsProjectId`** for those commands.
|
|
280
280
|
|
|
281
281
|
**Unknown command:** prints help and exits with a usage error.
|
|
282
282
|
|
package/commands.md
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# EasySpecs CLI — commands, flags, and configuration
|
|
2
2
|
|
|
3
|
-
**Error codes:** OS exit codes, structured
|
|
3
|
+
**Error codes:** OS exit codes, structured `**failureExitId`** values, and JSON field semantics are catalogued in `**[error-code.md](./error-code.md)**` (maintained with CLI changes).
|
|
4
4
|
|
|
5
|
-
Published package:
|
|
5
|
+
Published package: `**@gluecharm-lab/easyspecs-cli**` (`easyspecs-cli`). Source of truth for routing and option registration: `[src/cli/cliProgram.ts](../../src/cli/cliProgram.ts)`, command dispatch and business flow wiring: `[src/cli/main.ts](../../src/cli/main.ts)`, merged settings: `[mergeEasyspecsCliSettings](../../src/cli/cliSettings.ts)`, per-repo config: `[src/config/easyspecsConfigFile.ts](../../src/config/easyspecsConfigFile.ts)`, CLI API URL resolution: `[src/easyspecsApiBaseUrlCli.ts](../../src/easyspecsApiBaseUrlCli.ts)`. The VS Code extension resolves API URLs via `[src/apiBaseUrlResolve.ts](../../src/apiBaseUrlResolve.ts)`; `**easyspecs-cli` does not use that chain** for System Manager origin (**SRS-43 R30 / R34**).
|
|
6
6
|
|
|
7
7
|
### Vocabulary (SRS-53)
|
|
8
8
|
|
|
9
|
-
End-to-end behaviour and file layout: see the repo root companion
|
|
9
|
+
End-to-end behaviour and file layout: see the repo root companion `**run-analysis-flow.md`** (no URL; same repository).
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
|
14
|
-
| **
|
|
11
|
+
|
|
12
|
+
| Term | One-line meaning |
|
|
13
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
14
|
+
| **Factory** | The ordered **Generate Context** run (CLI: `**analysis`**; VS Code: Diagnosis **Run factory** / **Stop factory**). |
|
|
15
|
+
| **Pipeline** | A named stage the Factory composes: Synthesis, Coverage, Remediation, Link Mapping, Upload, or Download. |
|
|
15
16
|
| **Workstation** | One atomic unit inside a Pipeline (OpenCode agent + deterministic validators / repair loop, or a programmatic step). |
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
**Stderr tags (human TTY mode):** phase changes may insert a blank line when the family changes. Tags include `**[factory]`**, `**[pipeline:synthesis]**` (and `coverage`, `remediation`, `link-mapping`, `upload`, `download`), `**[workstation:<id>]**` for OpenCode subprocess lines, `**[pool]**` / `**[queue]**` for work queues, `**[deprecated-setting]**` when a legacy `**config.json**` key was consumed (canonical keys: `**easyspecs.factory.***`, `**easyspecs.workstations.***`, `**easyspecs.pipelines.upload.***` — see SRS-53 alias table). `**[ace]**` and `**[open questions]**` unchanged.
|
|
18
20
|
|
|
19
21
|
Quick usage:
|
|
20
22
|
|
|
@@ -24,41 +26,45 @@ easyspecs-cli help
|
|
|
24
26
|
|
|
25
27
|
### Factory validation reporting (**SRS-57**)
|
|
26
28
|
|
|
27
|
-
When
|
|
29
|
+
When `**easyspecs-cli analysis`** exits with **validation** (`**5`**), human stderr prints a short banner and **one bullet per failed factory phase** (readable label, `**validationExitId`** `**5.1`–`5.9**`, normative `**title**`, optional `**detail**`). `**--json**` adds:
|
|
30
|
+
|
|
28
31
|
|
|
29
|
-
| JSON key
|
|
30
|
-
|
|
|
31
|
-
| **`
|
|
32
|
-
| **`
|
|
33
|
-
| **`
|
|
34
|
-
| **`
|
|
35
|
-
| **`
|
|
32
|
+
| JSON key | Meaning |
|
|
33
|
+
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
34
|
+
| `**factoryFailures**` | Array of `**{ factory, phase, exitCode, failureExitId, title, validationExitId? (when exit 5), detail?, validationSubcode? }**` — `**failureExitId**` is the canonical `**major.minor**` id (SRS-58); see `[error-code.md](./error-code.md)`. |
|
|
35
|
+
| `**failurePhase**` | Last failed phase in macro order (alias for scripts). |
|
|
36
|
+
| `**validationExitId**` | Matching `**5.x**` for `**failurePhase**`. |
|
|
37
|
+
| `**exitMeaning**` | First failure `**title**`, or that title plus “and *N* other pipeline phases failed”. |
|
|
38
|
+
| `**error**` | Orchestrator message; if several phases failed, a short appendix lists extra `**validationExitId`**s (see `[factoryValidationFailures.ts](../../src/factory/factoryValidationFailures.ts)`). |
|
|
36
39
|
|
|
37
|
-
**`validationExitId` → `phase` map:** **`5.1`** `create_analysis_worktree`, **`5.2`** `materialize_opencode_agents`, **`5.3`** `synthesis_convergence`, **`5.4`** `reference_coverage`, **`5.5`** `zero_reference_remediation_convergence`, **`5.6`** `reference_coverage_execution_report`, **`5.7`** `link_mapping_pipeline`, **`5.8`** `assemble_application_context_index`, **`5.9`** `backend_context_sync`, **`5.0`** unknown / unattributed. Normative **`title`** strings and readable labels: [`.gluecharm/docs/srs/srs-57.md`](../../.gluecharm/docs/srs/srs-57.md).
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
`**validationExitId` → `phase` map:** `**5.1`** `create_analysis_worktree`, `**5.2**` `materialize_opencode_agents`, `**5.3**` `synthesis_convergence`, `**5.4**` `reference_coverage`, `**5.5**` `zero_reference_remediation_convergence`, `**5.6**` `reference_coverage_execution_report`, `**5.7**` `link_mapping_pipeline`, `**5.8**` `assemble_application_context_index`, `**5.9**` `backend_context_sync`, `**5.0**` unknown / unattributed. Normative `**title**` strings and readable labels: `[.gluecharm/docs/srs/srs-57.md](../../.gluecharm/docs/srs/srs-57.md)`.
|
|
42
|
+
|
|
43
|
+
**Optional `validationSubcode` (v1):** `**R5_MACRO_PING_PONG`** when synthesis `**detail**` notes **R5** unstable convergence; `**COVERAGE_PERCENT_THRESHOLD`** when reference-coverage `**detail**` matches the strict percent gate pattern.
|
|
40
44
|
|
|
41
45
|
---
|
|
42
46
|
|
|
43
47
|
## Global options
|
|
44
48
|
|
|
45
|
-
These flags may appear **before** the subcommand. Parsing and command registration are implemented with Commander in [
|
|
49
|
+
These flags may appear **before** the subcommand. Parsing and command registration are implemented with Commander in `[src/cli/cliProgram.ts](../../src/cli/cliProgram.ts)`, with command execution in `[src/cli/main.ts](../../src/cli/main.ts)`.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
| Flag | Effect |
|
|
53
|
+
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| `--cwd <dir>` | Repository root for git resolution and file paths (default: current working directory). |
|
|
55
|
+
| `--ci` | Non-interactive mode; feeds into merged settings (e.g. Factory outer-iteration default when unlimited). `**EASYSPECS_CI` is not read** — use this flag in CI. |
|
|
56
|
+
| `--json` | On supported exits, prints one JSON summary line on stdout; suppresses some human-oriented stderr unless `--verbose`. On `**analysis`** validation (**exit code 5**), the JSON line includes `**factoryFailures`** (**SRS-57** — one object per `**failed`** factory phase) plus `**failurePhase**`, `**validationExitId**`, composed `**error**`, and `**exitMeaning**` tailored to the first failure. |
|
|
57
|
+
| `--verbose` | Extra stderr logging where implemented. |
|
|
58
|
+
| `--api-base-url <url>` | System Manager API origin for this process (overrides `easyspecs.apiBaseUrl` in config). |
|
|
59
|
+
| `--environment production` | `--environment staging` | Alias: `**--env**`. Overrides `easyspecs.deploymentEnvironment` for built-in URL selection when no explicit URL is set. |
|
|
60
|
+
| `--promote` | After a successful `run synthesis`, copy generated `.gluecharm/context` from the analysis worktree into the workspace repo (when promotion is applicable). |
|
|
61
|
+
| `--no-promote` | Disable that promotion step for this run. |
|
|
62
|
+
| `--help`, `-h` | Show built-in help (also `help` as first positional). Does **not** create `.easyspecs/config.json`. |
|
|
63
|
+
| `--version`, `-V` | Print CLI package version (also `version` as first positional). Does **not** create config. |
|
|
64
|
+
| `--config <path>` | Parsed but **unused** by `main.ts` today; configuration is read from `<repoRoot>/.easyspecs/config.json`. |
|
|
46
65
|
|
|
47
|
-
| Flag | Effect |
|
|
48
|
-
|------|--------|
|
|
49
|
-
| `--cwd <dir>` | Repository root for git resolution and file paths (default: current working directory). |
|
|
50
|
-
| `--ci` | Non-interactive mode; feeds into merged settings (e.g. Factory outer-iteration default when unlimited). **`EASYSPECS_CI` is not read** — use this flag in CI. |
|
|
51
|
-
| `--json` | On supported exits, prints one JSON summary line on stdout; suppresses some human-oriented stderr unless `--verbose`. On **`analysis`** validation (**exit code 5**), the JSON line includes **`factoryFailures`** (**SRS-57** — one object per **`failed`** factory phase) plus **`failurePhase`**, **`validationExitId`**, composed **`error`**, and **`exitMeaning`** tailored to the first failure. |
|
|
52
|
-
| `--verbose` | Extra stderr logging where implemented. |
|
|
53
|
-
| `--api-base-url <url>` | System Manager API origin for this process (overrides `easyspecs.apiBaseUrl` in config). |
|
|
54
|
-
| `--environment production` \| `--environment staging` | Alias: **`--env`**. Overrides `easyspecs.deploymentEnvironment` for built-in URL selection when no explicit URL is set. |
|
|
55
|
-
| `--promote` | After a successful `run synthesis`, copy generated `.gluecharm/context` from the analysis worktree into the workspace repo (when promotion is applicable). |
|
|
56
|
-
| `--no-promote` | Disable that promotion step for this run. |
|
|
57
|
-
| `--help`, `-h` | Show built-in help (also `help` as first positional). Does **not** create `.easyspecs/config.json`. |
|
|
58
|
-
| `--version`, `-V` | Print CLI package version (also `version` as first positional). Does **not** create config. |
|
|
59
|
-
| `--config <path>` | Parsed but **unused** by `main.ts` today; configuration is read from `<repoRoot>/.easyspecs/config.json`. |
|
|
60
66
|
|
|
61
|
-
Environment (stderr styling):
|
|
67
|
+
Environment (stderr styling): `**NO_COLOR`** (any non-empty value) disables ANSI colors. `**FORCE_COLOR**` (any non-empty value) allows colors even when stderr is not a TTY. With `**--json**`, human stderr is normally suppressed; `**--json --verbose**` prints plain stderr **without** ANSI. In human mode, a **blank line** may be printed when the diagnostic **phase** changes (e.g. `**[factory]`** → `**[pool]**` / `**[workstation:listFeatures]**`). See **README** (Terminal diagnostics).
|
|
62
68
|
|
|
63
69
|
---
|
|
64
70
|
|
|
@@ -66,57 +72,61 @@ Environment (stderr styling): **`NO_COLOR`** (any non-empty value) disables ANSI
|
|
|
66
72
|
|
|
67
73
|
### File: `<repoRoot>/.easyspecs/config.json`
|
|
68
74
|
|
|
69
|
-
Canonical JSON created on first need (except
|
|
70
|
-
|
|
71
|
-
Merge uses **this file + global CLI flags only** — no `EASYSPECS_*` / `VITE_*` product overrides on
|
|
72
|
-
|
|
73
|
-
**Workspace layout (SRS-48):** For
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
|
78
|
-
| `
|
|
79
|
-
| `easyspecs.
|
|
80
|
-
| `easyspecs.
|
|
81
|
-
| `easyspecs.
|
|
82
|
-
| `easyspecs.
|
|
83
|
-
| `easyspecs.
|
|
84
|
-
| `easyspecs.
|
|
85
|
-
| `easyspecs.
|
|
86
|
-
| `easyspecs.
|
|
87
|
-
| `easyspecs.
|
|
88
|
-
| `easyspecs.
|
|
89
|
-
| `easyspecs.
|
|
90
|
-
| `easyspecs.
|
|
91
|
-
| `easyspecs.diagnose.
|
|
92
|
-
| `easyspecs.
|
|
93
|
-
| `easyspecs.upload.
|
|
94
|
-
| `easyspecs.upload.
|
|
95
|
-
| `easyspecs.
|
|
96
|
-
| `easyspecs.
|
|
75
|
+
Canonical JSON created on first need (except `**help`**, `**version**`, and `**doctor**` — no auto-create). Invalid JSON fails with a clear path (**R6**). Merged documents are also validated against **SRS-46** JSON Schema (`[srs-46-config.schema.json](../../.gluecharm/docs/srs/srs-46-config.schema.json)`) — see `[USER-MANUAL-SRS-46.md](../../.gluecharm/docs/srs/USER-MANUAL-SRS-46.md)`. If `**config.json`** is missing and `**.easyspecs/cli.json**` exists, settings are imported once (**§6 M2**) into the new file.
|
|
76
|
+
|
|
77
|
+
Merge uses **this file + global CLI flags only** — no `EASYSPECS_*` / `VITE_*` product overrides on `**easyspecs-cli`** (**R34**).
|
|
78
|
+
|
|
79
|
+
**Workspace layout (SRS-48):** For `**analysis`**, `**update context**`, `**diagnose**`, `**upload**`, `**download context**`, and `**context link-graph**`, the CLI creates the minimal `**.gluecharm/**` directories (`**docs/srs**`, `**content**`, `**logs**`, `**context**`) under the relevant filesystem root when they are missing. You do not need to copy a Gluecharm template tree before first use.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
| Path | Purpose |
|
|
83
|
+
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `schemaVersion` | Integer (e.g. `2`) for future migrations. |
|
|
85
|
+
| `easyspecs.deploymentEnvironment` | `production` or `staging` (default `production`). Used with built-in System Manager URLs when `apiBaseUrl` is empty. |
|
|
86
|
+
| `easyspecs.apiBaseUrl` | Explicit System Manager origin; wins after `--api-base-url`. Generated defaults use `**https://api.easyspecs.ai**` (production). Use `**""**` only if you want the built-in URL from `**deploymentEnvironment**` / `**--environment**` instead. |
|
|
87
|
+
| `easyspecs.easyspecsProjectId` | Optional EasySpecs **project** id (Content application UUID). **Only** store for uploads / Sync — set via `**Send context`**, `**Changes → Sync**`, `**config set-project-id**`, or `**easyspecs-cli**`. **`upload context`** / **`upload republish`** read **only** this field (merged `**easyspecs.applicationId`** legacy key maps here). |
|
|
88
|
+
| `easyspecs.defaultGitRemoteUrl` | Optional primary `**git remote**` URL (HTTPS or SSH) for documentation / tooling; analysis still uses the live repo. Related: `**index-application-context.json**` `repository`, `**.easyspecs/analysis-worktree.json**` `repositoryRoot`. |
|
|
89
|
+
| `easyspecs.cliSessionPath` | Repo-relative or absolute path to `**cli-session.json**` written by `**auth login**`. Empty `**""**` → `**~/.easyspecs/cli-session.json**`. Effective path: global `**--session-path**` (if passed) → `**cliSessionPath**` → default home path (`[cliSession.ts](../../src/cli/cliSession.ts)`). |
|
|
90
|
+
| `easyspecs.openCode` | `executable`, `skipCredentialsCheck` (legacy shortcut; see also `openCodeRuntime`). |
|
|
91
|
+
| `easyspecs.analysis.*` | Remaining analysis flags (e.g. `**promoteContextToWorkspace**`, ACE toggles). **SRS-46 cache** now lives under `**easyspecs.factory.cloudContextAnalyzed`** / `**…At**` (canonical); legacy `**easyspecs.analysis.cloudContext***` still read for one cycle. |
|
|
92
|
+
| `easyspecs.factory.*` | Factory: `**debug**` (stderr phase transitions; legacy `**easyspecs.macro.debug**`), backoff (`initialDelayMs`, `multiplier`, `maxDelayMs`), `maxOuterIterationsPerPipeline`, `maxPingPongCycles`, `synthesisRemediationShareBackoff`, cloud-context-analyzed cache. Legacy `**easyspecs.orchestration.***` aliases per SRS-53. |
|
|
93
|
+
| `easyspecs.workstations.*` | OpenCode argv template, timeouts, repair attempts, pool width, coordination lock timeout. Legacy `**easyspecs.analysis.openCodeTest***` / `**listJsonSchemaRepairAttempts**` / `**markdown***` / `**maxConcurrentOpenCodeAgents**` / `**coordinationListLockTimeoutMs**` aliases. |
|
|
94
|
+
| `easyspecs.pipelines.upload.useBatch` | Upload batching preference. Legacy `**easyspecs.analysis.uploadUseBatch**`. |
|
|
95
|
+
| `easyspecs.orchestration.*` | **Deprecated** — use `**easyspecs.factory.*`** (SRS-53); still merged when present. |
|
|
96
|
+
| `easyspecs.openCodeRuntime` | Annex-aligned block: `providers` (per-provider `apiKey`, `defaultModel`), `run`, `coordinationRepairs`, `pool`, `projectConfigOverlay` — see `[srs-43-opencode.schema.json](../../.gluecharm/docs/srs/srs-43-opencode.schema.json)`. |
|
|
97
|
+
| `easyspecs.diagnose.zeroReference.maxPercentNonReferenced` | `number` | `**null**`. When `**null**`, `diagnose reference-coverage` does not fail on percent alone (**SRS-44**). |
|
|
98
|
+
| `easyspecs.diagnose.coordinationDuplicates.strict` | Boolean (default `**true`**). When `**true**`, duplicate/orphan rows fail `diagnose coordination-duplicates`. |
|
|
99
|
+
| `easyspecs.upload.contextDirectory` | Repo-relative or absolute override for `**upload republish**` context dir; empty `**""**` → automatic (analysis snapshot). |
|
|
100
|
+
| `easyspecs.upload.fetchContextAnalyzedInCloud` | Boolean, default `**true**`. When `**true**`, after a fully successful `**upload context**` / `**upload republish**`, the CLI performs `**GET /api/content/application/:id**` and emits `**contextAnalyzedInCloud**` / `**contextAnalyzedInCloudAt**` on `**--json**`; updates `**easyspecs.factory.cloudContext***` cache (legacy `**easyspecs.analysis.cloudContext***`). When `**false**`, skips that GET and omits those JSON keys. |
|
|
101
|
+
| `easyspecs.upload.contextAnalyzedStatusTimeoutMs` | Optional positive integer (ms). GET timeout; default **15000** if omitted. |
|
|
102
|
+
| `easyspecs.cli.bundledResourcesRoot` | Optional path to bundled `**resources/`** (folder containing `**opencode-agents/**`). Empty → infer next to the CLI package. |
|
|
103
|
+
| `easyspecs.auth.ciLogin.email` / `password` | Used only with `**--ci**` when `**--email` / `--password**` are omitted (**SRS-44**). Prefer CI-generated `**config.json`**; do not commit secrets. |
|
|
104
|
+
|
|
97
105
|
|
|
98
106
|
### Resolved System Manager URL (`easyspecs-cli`)
|
|
99
107
|
|
|
100
|
-
**Order:** `--api-base-url` → non-empty `easyspecs.apiBaseUrl` → built-in URL from effective environment (
|
|
108
|
+
**Order:** `--api-base-url` → non-empty `easyspecs.apiBaseUrl` → built-in URL from effective environment (`**--environment`** `**easyspecs.deploymentEnvironment**` `**production**`). No `.env` / `process.env` product keys (**R30**).
|
|
101
109
|
|
|
102
|
-
Built-in defaults ship in [
|
|
110
|
+
Built-in defaults ship in `[src/easyspecsBuiltInApiUrls.ts](../../src/easyspecsBuiltInApiUrls.ts)`.
|
|
103
111
|
|
|
104
112
|
### No EasySpecs `EASYSPECS_*` configuration env (**SRS-44**)
|
|
105
113
|
|
|
106
|
-
|
|
114
|
+
`**easyspecs-cli`** does **not** read `**EASYSPECS_*`**, `**VITE_***`, or `**.env**` for product settings — use `**.easyspecs/config.json**` (+ global CLI flags) only. OS-level variables such as `**PATH**` still apply for finding `**node**`, `**opencode**`, `**git**`.
|
|
107
115
|
|
|
108
|
-
Provider API keys for OpenCode runs should live under
|
|
116
|
+
Provider API keys for OpenCode runs should live under `**easyspecs.openCodeRuntime.providers**` in `**config.json**`; they are injected into the **child** OpenCode process (**R13**) and redacted in `**doctor --inspect-config`** (**R17**).
|
|
109
117
|
|
|
110
118
|
---
|
|
111
119
|
|
|
112
120
|
## Diagnose / context flags
|
|
113
121
|
|
|
114
|
-
Used after `diagnose <subcommand>` or
|
|
122
|
+
Used after `diagnose <subcommand>` or `**context link-graph`**:
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
| Flag | Values | Meaning |
|
|
126
|
+
| ------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
127
|
+
| `--root` | `workspace` or `worktree` | Whether paths resolve against the workspace repo root or an analysis checkout (`[parseTailFlags](../../src/cli/parseTailFlags.ts)`). |
|
|
128
|
+
| `--worktree` | path | Analysis git checkout (required for `--root worktree` when no path embedded in `--root` flow; combined with explicit `--worktree` — see `main.ts`). |
|
|
115
129
|
|
|
116
|
-
| Flag | Values | Meaning |
|
|
117
|
-
|------|--------|---------|
|
|
118
|
-
| `--root` | `workspace` or `worktree` | Whether paths resolve against the workspace repo root or an analysis checkout ([`parseTailFlags`](../../src/cli/parseTailFlags.ts)). |
|
|
119
|
-
| `--worktree` | path | Analysis git checkout (required for `--root worktree` when no path embedded in `--root` flow; combined with explicit `--worktree` — see `main.ts`). |
|
|
120
130
|
|
|
121
131
|
---
|
|
122
132
|
|
|
@@ -124,40 +134,48 @@ Used after `diagnose <subcommand>` or **`context link-graph`**:
|
|
|
124
134
|
|
|
125
135
|
Each row lists **command-specific CLI tokens**, then **what configuration applies**.
|
|
126
136
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `config
|
|
134
|
-
| `config set-
|
|
135
|
-
| `
|
|
136
|
-
| `auth
|
|
137
|
-
| `auth
|
|
138
|
-
| `
|
|
139
|
-
| `run synthesis
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `diagnose
|
|
144
|
-
| `diagnose
|
|
145
|
-
| `diagnose
|
|
146
|
-
| `diagnose
|
|
147
|
-
| `
|
|
148
|
-
| `context
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `upload
|
|
152
|
-
| `
|
|
153
|
-
| `ace
|
|
154
|
-
| `ace
|
|
137
|
+
|
|
138
|
+
| Command | Command-specific flags / tokens | Configuration & notes |
|
|
139
|
+
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `help`, `--help` | — | Global options only; prints usage. |
|
|
141
|
+
| `version` | — | Prints `[PKG_VERSION](../../src/cli/main.ts)` from the bundle. |
|
|
142
|
+
| `doctor` | Optional `**--readiness`**, `**--inspect-config**` | **Does not** create `config.json`. Default (no flags) = `**--readiness`**: repo root, resolved API URL, OpenCode installed/credentials, agents dir. `**--inspect-config**` alone: redacted `**merged**` + `**easyspecsConfig**`. `**--readiness --inspect-config**`: both. Global flags apply (`**--cwd**`, `**--ci**`, `**--api-base-url**`, `**--session-path**`, `**--environment**`, `**--promote**` / `**--no-promote**`). |
|
|
143
|
+
| `config init` | Optional `**--overwrite**` | Creates `**<repo>/.easyspecs/config.json**` with full defaults if missing; imports legacy `**cli.json**` / `**settings.json**` (ACE) when present, same as first-time bootstrap. If the file already exists, does nothing unless `**--overwrite**` (replaces with that bootstrap content). Does not run other commands. |
|
|
144
|
+
| `config set-project-id <id>` | — | Writes `**easyspecs.easyspecsProjectId**` to `**config.json**`, replacing any previous value. Creates `**config.json**` (defaults + legacy import) if missing. |
|
|
145
|
+
| `config set-git-remote <url>` | — | Writes `**easyspecs.defaultGitRemoteUrl**` to `**config.json**`, replacing any previous value. Same bootstrap-if-missing behaviour as `**set-project-id**`. |
|
|
146
|
+
| `auth login` | `**--email <email> --password <password>**`, optional `**--session-path <path>**` (tail; updates `**config.json**`) | Calls `**POST /api/authentication/login**`. On success prints `**OK**` (stdout), exit **0**, and writes tokens + `**apiBaseUrl`** to the session file. Tail `**--session-path**` updates `**easyspecs.cliSessionPath**` in `**config.json**` (normalized repo-relative when under the repo) and writes the session there for this run; omit it to use the existing `**easyspecs.cliSessionPath**` / default `**~/.easyspecs/cli-session.json**`. Global `**--session-path**` (before the command) overrides the effective session file for any command without changing `**config.json**`. On failure prints `**KO: …**` (stderr), exit `**auth**`. `**easyspecs-cli --ci auth login**` without argv credentials uses `**easyspecs.auth.ciLogin**` in `**config.json**`. `**--password**` on argv is visible to `**ps**`. |
|
|
147
|
+
| `auth logout` | — | Deletes the effective session file (same path rules as `**auth login**`). |
|
|
148
|
+
| `auth status` | — | Reads session file. |
|
|
149
|
+
| `run synthesis` | — | Single SRS-9 context pass (same as extension **Run Analysis**). `**requireOpenCode`** → executable + credentials unless skip flag. Uses `**merged.pipelineOpenCode**` from `**config.json**`. `**--promote` / `--no-promote**` controls promotion after success. |
|
|
150
|
+
| `run synthesis resume-missing`, `run synthesis resume-synthesis` | Optional `**--worktree <path>**` | Same implementation: resolves checkout via `--worktree` or stored snapshot (`[resolveAdHocCheckoutRoot](../../src/cli/main.ts)`). OpenCode + `**merged.pipelineOpenCode**`. |
|
|
151
|
+
| `analysis` | Optional tail: `**--force-new-context-analysis**`. **`--upload`** → usage exit. **`--synthesis-only`**: accepted as a **hidden** Commander option (legacy scripts); **ignored** with one stderr **`[deprecated]`** line (**SRS-60**). | **SRS-32** full **Factory** loop: synthesis convergence (until no missing artefacts), coverage, zero-ref, report, **link mapping**, index assembly; **Phase 7** backend sync is skipped in CLI (**`skipBackendSync`**). Push context with **`upload context`** / **`upload republish`** after analysis. Factory timing from `**merged.factory`** + `**--ci**` defaults. Debug: `**easyspecs.factory.debug**`. OpenCode options from `**merged.pipelineOpenCode**`. **SRS-46:** if `**easyspecs.factory.cloudContextAnalyzed`** is `**true**` and `**--force-new-context-analysis**` is absent, exits **0** without running the Factory (`**analysisSkipped**`, …). **SRS-59:** stale worktree registration recovery — see **§ Analysis git checkout** below. |
|
|
152
|
+
| `update context` | — (no subcommand flags; **SRS-60** removed `**--upload**`) | **SRS-55:** incremental context refresh — baseline → git delta → worktree → `**changes-since-date.md`** → optional remediation → **`--promote` / `--no-promote**` (global) → persist `**lastRunAt**`. Run **`upload context`** separately if you need cloud sync. |
|
|
153
|
+
| `diagnose reference-coverage` | `**--root workspace**` | `**--root worktree**`, optional `**--worktree <path>**` | Gate when `**easyspecs.diagnose.zeroReference.maxPercentNonReferenced**` is a finite number (not `**null**`): failure when metric exceeds it. |
|
|
154
|
+
| `diagnose coordination-duplicates` | Same `**--root**` / `**--worktree**` | `**easyspecs.diagnose.coordinationDuplicates.strict**`: when `**true**` (default), duplicate/orphan issues fail the exit code. |
|
|
155
|
+
| `diagnose coverage-report` | Same `**--root**` / `**--worktree**` | Uses repo/worktree paths only; no extra env in `main.ts`. |
|
|
156
|
+
| `diagnose missing-artefacts` | Same `**--root**` / `**--worktree**` | Reads artefact snapshot from workspace state; no OpenCode. |
|
|
157
|
+
| `diagnose zero-reference` | Optional `**--worktree <path>**` (no `--root` branch in this handler) | `**requireOpenCode**`; `**merged.pipelineOpenCode**` for pool concurrency/argv/timeout. Checkout from `**--worktree**` or snapshot (`[resolveAdHocCheckoutRoot](../../src/cli/main.ts)`). On full success, runs **SRS-51** markdown link graph on `**<checkout>/.gluecharm/context`** before exit (**non-zero** if link validation fails). |
|
|
158
|
+
| `context link-graph` | `**--root workspace`** | `**--root worktree**`, optional `**--worktree <path>**` | **SRS-51:** deterministic navigation sections in context markdown under `**<root>/.gluecharm/context`**. No OpenCode. `**--json**`: `**ok**`, `**contextDir**`, `**error**`, `**brokenLinks**`. Exit `**validation**` on broken relative links inside EasySpecs nav regions. |
|
|
159
|
+
| `context drift <referencePath>` | `**--label <slug>**`, `**--index <path>**`, `**--dry-run**`. Optional `**--root**` / `**--worktree**` tail tokens are accepted and ignored for v1 routing. | **SRS-56:** analysis worktree → OpenCode drift agent → `**.gluecharm/context/drift/drift-<slug>-<date>.md`** + reference index patch → global `**--promote` / `--no-promote**`. Success stdout: drift report path. |
|
|
160
|
+
| `download context` | Optional `**--force**`, `**--replace-from-cloud**` | **SRS-49:** requires `**auth`** session. `**GET /api/content/application/:id**` → `**srs_discovery**` ids → `**POST /api/batch/content/srs_discovery/get**` → writes files under `**<repoRoot>/.gluecharm/context**`. `**--force**` overwrites existing paths; `**--replace-from-cloud**` deletes local context files first (preserves root `**easyspecs-upload-target.json**`). `**--json**` stdout: `**downloaded**`, `**skipped**`, `**failed**`, `**localRemoved**`. Exit `**upload**` when any row fails. |
|
|
161
|
+
| `upload context` | — | Requires `**auth**` session. Context dir: `**<repoRoot>/.gluecharm/context**`. Project id: `**easyspecs.easyspecsProjectId**` in `**config.json**` only. **SRS-46:** on full success, optional cloud status GET (see `**fetchContextAnalyzedInCloud`**); `**--json**` may add `**contextAnalyzedInCloud**` / `**contextAnalyzedInCloudAt**`; updates `**easyspecs.factory.cloudContext***` when fetch is enabled (legacy `**easyspecs.analysis.cloudContext***`). |
|
|
162
|
+
| `upload republish` | — | Same auth + upload pipeline; context dir from `**easyspecs.upload.contextDirectory**` if non-empty and valid, else analysis worktree `**…/.gluecharm/context**` from snapshot, else error. Same project id rule as `**upload context**`. Same **SRS-46** JSON + cache behaviour as `**upload context`**. |
|
|
163
|
+
| `ace clear` | — | Deletes `**<repoRoot>/.gluecharm/context/learnings**`. |
|
|
164
|
+
| `ace learn` | Optional `**--worktree <path>**` | `**requireOpenCode**`; worktree chosen if `--worktree` points at checkout with `**.opencode/schemas/ace**`, else `**repoRoot**` (`[main.ts](../../src/cli/main.ts)`). `**merged.pipelineOpenCode**` for spawn argv/timeout. |
|
|
165
|
+
| `ace auto-learn` | Optional `**--worktree <path>**` | `**requireOpenCode**`; checkout = `--worktree` if valid git dir, else `**repoRoot**`. `**merged.pipelineOpenCode.maxConcurrentOpenCodeAgents**` caps parallelism. |
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
### Analysis git checkout (**SRS-59**)
|
|
169
|
+
|
|
170
|
+
The Factory creates a **detached** analysis checkout under `**$TMPDIR/easyspecs-analysis/easyspecs-NNN`** (`[worktreeManager.ts](../../src/analysis/worktreeManager.ts)`). If the OS removes that folder (or it is deleted) **without** `**git worktree remove`**, Git may still list the path and `**git worktree add**` fails with *missing but already registered worktree*. **SRS-59:** `**easyspecs-cli*`* detects that failure class, runs `**git worktree prune**` with `**cwd**` = the repository root (from `**--cwd**` / current directory), then retries `**git worktree add**` **once** at the same allocated path (`[gitWorktreeStaleRecovery.ts](../../src/analysis/gitWorktreeStaleRecovery.ts)`). Stderr may include `**[worktree] git worktree prune — cleared stale registration for <folder> (<absolute path>)`** before the retry. Manual troubleshooting: `[.gluecharm/docs/srs/USER-MANUAL-SRS-59.md](../../.gluecharm/docs/srs/USER-MANUAL-SRS-59.md)`.
|
|
155
171
|
|
|
156
172
|
---
|
|
157
173
|
|
|
158
174
|
## Notes
|
|
159
175
|
|
|
160
|
-
- Commands that **spawn OpenCode** call
|
|
161
|
-
-
|
|
176
|
+
- Commands that **spawn OpenCode** call `**requireOpenCode`**: binary must respond (`easyspecs.openCode.executable` / `opencode` on `**PATH**`), and credentials must look ready unless `**easyspecs.openCode.skipCredentialsCheck**`, or provider keys exist in `**config.json**`, or the parent shell already has provider env (probe behaviour in `[opencodeCli](../../src/opencodeCli.ts)`).
|
|
177
|
+
- `**download context**` / `**upload context**` / `**upload republish**` require a prior `**auth login**` session (`**--email**` / `**--password**`, or `**--ci**` with `**easyspecs.auth.ciLogin**` in `**config.json**`).
|
|
162
178
|
- Unknown commands print help and exit with a usage error.
|
|
163
|
-
- Git subprocesses may set
|
|
179
|
+
- Git subprocesses may set `**GIT_TERMINAL_PROMPT=0**` on the child environment (`[runCoveragePipeline](../../src/pipelines/coverage/coveragePipeline.ts)`).
|
|
180
|
+
- Any command path that **creates** the analysis git worktree (`**analysis`**, `**run synthesis**`, `**update context**`, `**context drift**` without `**--dry-run**`, etc.) benefits from **SRS-59** stale-registration recovery in `**createAnalysisWorktree`**, not only `**analysis**`.
|
|
181
|
+
|