@inharness-ai/claude4spec 1.0.5 → 1.0.6
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/skills/c4s-brief-implementer/SKILL.md +37 -3
- package/.claude/skills/c4s-spec-reader/SKILL.md +11 -0
- package/CHANGELOG.md +16 -0
- package/dist/bin/c4s/commands/ask.d.ts +6 -4
- package/dist/bin/c4s/commands/ask.js +41 -135
- package/dist/bin/c4s/commands/ask.js.map +1 -1
- package/dist/client/assets/{arc-grMo2vzL.js → arc-CqFoQdai.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Fp_VHONq.js → architectureDiagram-3BPJPVTR-CIEQ1CV_.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CIwVG0sx.js → blockDiagram-GPEHLZMM-DwCCDYZs.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-tysuJyz0.js → c4Diagram-AAUBKEIU-DB988zZs.js} +1 -1
- package/dist/client/assets/channel-mXCQ_joU.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-DZFNNwID.js → chunk-2J33WTMH-Bwc9B4Id.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-CsnJG7Pv.js → chunk-4BX2VUAB-ClOw-zt3.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-MhREYXzo.js → chunk-55IACEB6-B513D_Oz.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-BjvyGtK3.js → chunk-727SXJPM-CvT-ppRD.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-zfcfKNbO.js → chunk-AQP2D5EJ-BDZ-uKjF.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Ckx-Hc8U.js → chunk-FMBD7UC4-DlnsCvyP.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-DSIVVmYM.js → chunk-ND2GUHAM-Cv4kIfqi.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-EcIM6ZdS.js → chunk-QZHKN3VN-Boyq-O-A.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CvLk0Sg1.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CvLk0Sg1.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DC8DVe0z.js → cose-bilkent-S5V4N54A-B4fXXqZV.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-BQjcdXnw.js → dagre-BM42HDAG-D7JvdAaj.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BUPeBMwt.js → diagram-2AECGRRQ-TqVC9_06.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-I_Q-Pnp6.js → diagram-5GNKFQAL-BJE7Sfvp.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-B8WbbWJu.js → diagram-KO2AKTUF-dDI3Q4Xy.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CsACxgW7.js → diagram-LMA3HP47-zrNXdbAH.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-lPuJxQED.js → diagram-OG6HWLK6-C9RoGREB.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-cU5ZGREz.js → erDiagram-TEJ5UH35-BIOg0Mgx.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-Dr-vZTBV.js → flowDiagram-I6XJVG4X-C5olRPEY.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CXiWZ0R8.js → ganttDiagram-6RSMTGT7-Daqt3_2M.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-PDvLBbvz.js → gitGraphDiagram-PVQCEYII-E09LH7cR.js} +1 -1
- package/dist/client/assets/{index-RMlMPKY7.js → index-BwbjYrNH.js} +1 -1
- package/dist/client/assets/{index-BQltseJ-.js → index-CMsZQS3t.js} +1 -1
- package/dist/client/assets/{index-YFPhJxE5.js → index-CUhhC6SY.js} +151 -146
- package/dist/client/assets/{infoDiagram-5YYISTIA-Re9fOUPS.js → infoDiagram-5YYISTIA-Cy_D0LmA.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BTazB_7p.js → ishikawaDiagram-YF4QCWOH-B3cvnpaf.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-pGUoqxHl.js → journeyDiagram-JHISSGLW-IR8sEnrO.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-C2RzCJrM.js → kanban-definition-UN3LZRKU-DHaqk7jz.js} +1 -1
- package/dist/client/assets/{linear-Be3WPYKf.js → linear-BJO3kbAY.js} +1 -1
- package/dist/client/assets/{mermaid.core-GdPXct3q.js → mermaid.core-Dwygsmt4.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DvktVTUU.js → mindmap-definition-RKZ34NQL-C9XVPJV6.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DvC_m4m5.js → pieDiagram-4H26LBE5-CZldRk6l.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-SWtidcZL.js → quadrantDiagram-W4KKPZXB-CY053ghg.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CQEHDx1W.js → requirementDiagram-4Y6WPE33-DQbMS7j1.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-C0PTA3gP.js → sankeyDiagram-5OEKKPKP-C5w3huvN.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-D-x7SXoo.js → sequenceDiagram-3UESZ5HK-nF1GikPI.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-BhcGVfs1.js → stateDiagram-AJRCARHV-CxjKXGSz.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CLYCEwSk.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-JYTlKPB-.js → timeline-definition-PNZ67QCA-q0ZvTC5H.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-KjNL1Qpz.js → vennDiagram-CIIHVFJN-CO7sztp2.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-DcljmmEY.js → wardley-L42UT6IY-JeTZFzC9.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Pbq6ALgg.js → wardleyDiagram-YWT4CUSO-COpCQvmO.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-G_r_2Cvk.js → xychartDiagram-2RQKCTM6-C78ptl5b.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/core/ask/run-ask.d.ts +37 -0
- package/dist/core/ask/run-ask.js +171 -0
- package/dist/core/ask/run-ask.js.map +1 -0
- package/dist/server/core/plugin-host/host.js +8 -8
- package/dist/server/core/plugin-host/host.js.map +1 -1
- package/dist/server/core/plugin-host/types.d.ts +22 -7
- package/dist/server/entities/ac/plugin.js +1 -1
- package/dist/server/entities/ac/plugin.js.map +1 -1
- package/dist/server/entities/database-table/plugin.js +1 -1
- package/dist/server/entities/database-table/plugin.js.map +1 -1
- package/dist/server/entities/dto/plugin.js +1 -1
- package/dist/server/entities/dto/plugin.js.map +1 -1
- package/dist/server/entities/endpoint/plugin.js +1 -1
- package/dist/server/entities/endpoint/plugin.js.map +1 -1
- package/dist/server/entities/ui-view/plugin.js +1 -1
- package/dist/server/entities/ui-view/plugin.js.map +1 -1
- package/dist/server/external-skills/brief-implementer-template.d.ts +1 -1
- package/dist/server/external-skills/brief-implementer-template.js +18 -14
- package/dist/server/external-skills/brief-implementer-template.js.map +1 -1
- package/dist/server/index.js +5 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/brief-tools.d.ts +2 -4
- package/dist/server/mcp/brief-tools.js +4 -25
- package/dist/server/mcp/brief-tools.js.map +1 -1
- package/dist/server/mcp/c4s-tools.d.ts +15 -0
- package/dist/server/mcp/c4s-tools.js +67 -0
- package/dist/server/mcp/c4s-tools.js.map +1 -0
- package/dist/server/routes/agent-turn.js +9 -2
- package/dist/server/routes/agent-turn.js.map +1 -1
- package/dist/server/services/chat-context.d.ts +4 -0
- package/dist/server/services/chat-context.js +24 -6
- package/dist/server/services/chat-context.js.map +1 -1
- package/dist/server/skills/brief-author/SKILL.md +0 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-B30S19wt.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-Bm4SZLsb.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bm4SZLsb.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-2vcyLY1V.js +0 -1
|
@@ -37,13 +37,31 @@ type: brief
|
|
|
37
37
|
from_release: v0.1.16
|
|
38
38
|
to_release: v0.1.17
|
|
39
39
|
generator_version: brief-author@0.1
|
|
40
|
-
|
|
40
|
+
implemented: false
|
|
41
41
|
---
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
The body contains everything you need — entity snapshots, section diffs, the
|
|
45
45
|
narrative of what changes, and acceptance criteria. **Do not read the main
|
|
46
|
-
specification.**
|
|
46
|
+
specification.**
|
|
47
|
+
|
|
48
|
+
If the brief is unclear — a missing detail, an ambiguous wording, a decision
|
|
49
|
+
you'd otherwise have to guess — you have two paths:
|
|
50
|
+
|
|
51
|
+
**Synchronous (preferred when available).** Ask the specification agent in the
|
|
52
|
+
same terminal and continue once you have an answer:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
c4s ask "Brief nie precyzuje X — czy chodzi o A czy B?" --ct brief --brief <brief-slug>.md
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Continue the same thread with `c4s ask "..." --thread <threadId>` (the
|
|
59
|
+
`threadId` is printed with the answer). This path requires `c4s` installed
|
|
60
|
+
*and* a running `npx claude4spec` server. When either is unavailable, skip it.
|
|
61
|
+
|
|
62
|
+
**Asynchronous (always available).** If you cannot ask synchronously, proceed
|
|
63
|
+
with your best judgement and file a patch afterwards (step 4) so the
|
|
64
|
+
spec-author can fold the clarification into the next brief.
|
|
47
65
|
|
|
48
66
|
### 3. Implement
|
|
49
67
|
|
|
@@ -93,7 +111,23 @@ Patch-kind values:
|
|
|
93
111
|
The `.claude4spec/patches/` directory is created **lazily** — only when you
|
|
94
112
|
file your first patch. The claude4spec server does NOT create it.
|
|
95
113
|
|
|
96
|
-
### 5.
|
|
114
|
+
### 5. Mark brief as implemented
|
|
115
|
+
|
|
116
|
+
When the implementation is genuinely finished — code committed, tests green,
|
|
117
|
+
merged to main / accepted by the user — flip the brief's frontmatter to
|
|
118
|
+
`implemented: true`:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Option A — Edit tool: change the line `implemented: false` → `implemented: true`.
|
|
122
|
+
# Option B — yq (idempotent; adds the field to legacy briefs that never had it):
|
|
123
|
+
yq -i '.implemented = true' .claude4spec/briefs/<brief-slug>.md
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`implemented: true` is a **declaration**, not a computed fact derived from git.
|
|
127
|
+
A revert on main does NOT roll the flag back. Set it ONLY when implementation
|
|
128
|
+
is realistically done — never proactively or "just in case".
|
|
129
|
+
|
|
130
|
+
### 6. Hand-off
|
|
97
131
|
|
|
98
132
|
The spec-author reads patches manually (`ls .claude4spec/patches/`, `cat`)
|
|
99
133
|
and folds them into the next brief or entity edits. There is no UI listing in
|
|
@@ -44,3 +44,14 @@ an exit code > 0.
|
|
|
44
44
|
|
|
45
45
|
The database is opened **read-only** — `c4s` never mutates the project.
|
|
46
46
|
|
|
47
|
+
## Asking the spec agent
|
|
48
|
+
|
|
49
|
+
When a question goes beyond resolving entities or pages, `c4s ask` runs a
|
|
50
|
+
synchronous agent turn against the specification:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
c4s ask "<question>" --ct chat
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Unlike the read-only commands above, `c4s ask` requires a running
|
|
57
|
+
`npx claude4spec` server (it delegates the turn to the server's agent).
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.6] - 2026-05-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `c4s-tools` MCP server — exposes the cross-spec `c4s ask` Q&A flow over MCP, so it works in plan mode where Bash tools are filtered out. The plugin host registers MCP server factories and builds a fresh instance per turn.
|
|
12
|
+
- Brief "implemented" workflow, with a status pill and collapsible patch view in the UI.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Extracted the shared `ask` logic into `src/core/ask/run-ask.ts`; the `c4s ask` CLI is now a thin wrapper over it.
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
- `list_brief_versions` / `get_brief_version` tools from the brief-tools MCP surface.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Restored a green client typecheck (`tsconfig.client.json`): widened the sidebar-tab `icon` contract to accept lucide-react's `size?: number | string`, and guarded `Tag.counts[...]` lookups against `undefined` under `noUncheckedIndexedAccess`.
|
|
22
|
+
|
|
8
23
|
## [1.0.5] - 2026-05-19
|
|
9
24
|
|
|
10
25
|
### Added
|
|
@@ -59,6 +74,7 @@ Initial public release.
|
|
|
59
74
|
- Acceptance Criteria entity and tooling.
|
|
60
75
|
- Briefs and patches workflow for spec-driven implementation.
|
|
61
76
|
|
|
77
|
+
[1.0.6]: https://github.com/InHarness/claude4spec/compare/v1.0.5...v1.0.6
|
|
62
78
|
[1.0.5]: https://github.com/InHarness/claude4spec/compare/v1.0.4...v1.0.5
|
|
63
79
|
[1.0.4]: https://github.com/InHarness/claude4spec/compare/v1.0.3...v1.0.4
|
|
64
80
|
[1.0.3]: https://github.com/InHarness/claude4spec/compare/v1.0.2...v1.0.3
|
|
@@ -2,12 +2,14 @@ import type { ParsedArgs } from '../args.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* `c4s ask` — synchroniczny kanal Q&A z agentem specyfikacji (M11).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Cienki wrapper nad `runAsk(...)` z `core/ask/run-ask.ts`. Wspolne ciezary
|
|
6
|
+
* (resolve project, health-check, create-thread, run-turn) zyja w core'rze;
|
|
7
|
+
* tutaj zostala tylko warstwa CLI: parsowanie flag, mapowanie kodow bledow
|
|
8
|
+
* na `CliError`, formatowanie outputu (stdout/stderr split, --format json|text).
|
|
8
9
|
*
|
|
9
10
|
* c4s ask "<msg>" --ct chat
|
|
10
11
|
* c4s ask "<msg>" --ct brief --brief <path>
|
|
11
12
|
* c4s ask "<msg>" --thread <id>
|
|
12
13
|
*/
|
|
13
|
-
export declare function
|
|
14
|
+
export declare function runAsk_cli(args: ParsedArgs): Promise<void>;
|
|
15
|
+
export { runAsk_cli as runAsk };
|
|
@@ -1,167 +1,73 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
1
|
import { optionalString } from '../args.js';
|
|
4
2
|
import { CliError } from '../errors.js';
|
|
5
|
-
import {
|
|
3
|
+
import { AskError, runAsk } from '../../../core/ask/run-ask.js';
|
|
6
4
|
/**
|
|
7
5
|
* `c4s ask` — synchroniczny kanal Q&A z agentem specyfikacji (M11).
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Cienki wrapper nad `runAsk(...)` z `core/ask/run-ask.ts`. Wspolne ciezary
|
|
8
|
+
* (resolve project, health-check, create-thread, run-turn) zyja w core'rze;
|
|
9
|
+
* tutaj zostala tylko warstwa CLI: parsowanie flag, mapowanie kodow bledow
|
|
10
|
+
* na `CliError`, formatowanie outputu (stdout/stderr split, --format json|text).
|
|
12
11
|
*
|
|
13
12
|
* c4s ask "<msg>" --ct chat
|
|
14
13
|
* c4s ask "<msg>" --ct brief --brief <path>
|
|
15
14
|
* c4s ask "<msg>" --thread <id>
|
|
16
15
|
*/
|
|
17
|
-
export async function
|
|
16
|
+
export async function runAsk_cli(args) {
|
|
18
17
|
const message = args.positional[0];
|
|
19
18
|
if (!message || !message.trim()) {
|
|
20
19
|
throw new CliError('INVALID_ARGS', 'message is required: c4s ask "<msg>" --ct chat');
|
|
21
20
|
}
|
|
22
|
-
const
|
|
21
|
+
const threadId = optionalString(args, 'thread');
|
|
23
22
|
const ct = optionalString(args, 'ct');
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
// --- health-check tozsamosci --------------------------------------------
|
|
37
|
-
await healthCheck(baseUrl);
|
|
38
|
-
// --- create-thread (context-specific) — pomijany dla --thread -----------
|
|
39
|
-
let threadId;
|
|
40
|
-
if (threadFlag) {
|
|
41
|
-
threadId = threadFlag;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
23
|
+
const briefPath = optionalString(args, 'brief');
|
|
24
|
+
const server = optionalString(args, 'server');
|
|
25
|
+
const project = args.project;
|
|
26
|
+
if (project && server) {
|
|
27
|
+
// Mutex `project` vs `server` — gdy oba podane, `server` wygrywa; CLI
|
|
28
|
+
// dopisuje warning na stderr (dla MCP analogicznie, ale przez tool_result).
|
|
29
|
+
process.stderr.write('warning: both --project and --server given; --server wins, --project ignored\n');
|
|
30
|
+
}
|
|
31
|
+
if (!threadId) {
|
|
32
|
+
// Wczesna walidacja flag CLI (drobne komunikaty user-facing); runAsk
|
|
33
|
+
// robi to samo na poziomie biblioteki, ale tutaj dajemy zywsze hinty.
|
|
44
34
|
if (ct !== 'chat' && ct !== 'brief' && ct !== 'patch') {
|
|
45
35
|
throw new CliError('INVALID_ARGS', '--ct must be chat|brief|patch (or pass --thread <id> to continue a thread)');
|
|
46
36
|
}
|
|
47
37
|
if (ct === 'patch') {
|
|
48
|
-
// Watki patch nie maja CLI route create-thread — tylko kontynuacja.
|
|
49
38
|
throw new CliError('INVALID_ARGS', 'c4s ask cannot create a patch thread; pass --thread <id> to continue one');
|
|
50
39
|
}
|
|
51
|
-
if (ct === 'brief') {
|
|
52
|
-
|
|
53
|
-
throw new CliError('INVALID_ARGS', '--ct brief requires --brief <path>');
|
|
54
|
-
}
|
|
55
|
-
const encoded = briefFlag.split('/').map(encodeURIComponent).join('/');
|
|
56
|
-
const created = await postJson(`${baseUrl}/api/briefs/${encoded}/threads`, {});
|
|
57
|
-
threadId = pickThreadId(created);
|
|
40
|
+
if (ct === 'brief' && !briefPath) {
|
|
41
|
+
throw new CliError('INVALID_ARGS', '--ct brief requires --brief <path>');
|
|
58
42
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
}
|
|
44
|
+
let result;
|
|
45
|
+
try {
|
|
46
|
+
result = await runAsk({
|
|
47
|
+
message,
|
|
48
|
+
project,
|
|
49
|
+
server,
|
|
50
|
+
contextType: ct,
|
|
51
|
+
threadId,
|
|
52
|
+
briefPath,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (err instanceof AskError) {
|
|
57
|
+
throw new CliError(err.code, err.message, err.hint);
|
|
62
58
|
}
|
|
59
|
+
throw err;
|
|
63
60
|
}
|
|
64
|
-
// --- run-turn (generyczny po context_type) ------------------------------
|
|
65
|
-
const result = await postJson(`${baseUrl}/api/threads/${encodeURIComponent(threadId)}/ask`, {
|
|
66
|
-
message,
|
|
67
|
-
});
|
|
68
|
-
const answer = typeof result.answer === 'string' ? result.answer : '';
|
|
69
|
-
const outThreadId = typeof result.threadId === 'string' ? result.threadId : threadId;
|
|
70
61
|
// --- output --------------------------------------------------------------
|
|
71
62
|
if (args.format === 'text') {
|
|
72
|
-
process.stdout.write(answer + '\n');
|
|
63
|
+
process.stdout.write(result.answer + '\n');
|
|
73
64
|
// threadId na stderr — hint do kontynuacji wątku.
|
|
74
|
-
process.stderr.write(`thread: ${
|
|
65
|
+
process.stderr.write(`thread: ${result.threadId} (continue: c4s ask "..." --thread ${result.threadId})\n`);
|
|
75
66
|
}
|
|
76
67
|
else {
|
|
77
|
-
process.stdout.write(JSON.stringify({ threadId:
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/** Czyta `.claude4spec/config.json` i zwraca `port`. */
|
|
81
|
-
function readConfigPort(projectDir) {
|
|
82
|
-
const file = path.join(projectDir, '.claude4spec', 'config.json');
|
|
83
|
-
let parsed;
|
|
84
|
-
try {
|
|
85
|
-
parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
86
|
-
}
|
|
87
|
-
catch (err) {
|
|
88
|
-
throw new CliError('PROJECT_NOT_FOUND', `cannot read ${file}: ${err.message}`);
|
|
89
|
-
}
|
|
90
|
-
const port = parsed.port;
|
|
91
|
-
if (typeof port !== 'number') {
|
|
92
|
-
throw new CliError('PROJECT_NOT_FOUND', `config.json has no numeric "port" (${file})`);
|
|
93
|
-
}
|
|
94
|
-
return port;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Health-check tozsamosci: `GET /api/config` musi zwrocic kształt configu
|
|
98
|
-
* claude4spec. Trzy rozlaczne wyniki: connection refused → SERVER_NOT_RUNNING;
|
|
99
|
-
* odpowiedz spoza configu → SERVER_NOT_RECOGNIZED; poprawny config → OK.
|
|
100
|
-
*/
|
|
101
|
-
async function healthCheck(baseUrl) {
|
|
102
|
-
let res;
|
|
103
|
-
try {
|
|
104
|
-
res = await fetch(`${baseUrl}/api/config`);
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
throw new CliError('SERVER_NOT_RUNNING', `no claude4spec server responding at ${baseUrl}`, 'start it with `npx claude4spec` in the project');
|
|
108
|
-
}
|
|
109
|
-
let body;
|
|
110
|
-
try {
|
|
111
|
-
body = await res.json();
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
throw new CliError('SERVER_NOT_RECOGNIZED', `process at ${baseUrl} responded but not with a claude4spec config`);
|
|
115
|
-
}
|
|
116
|
-
if (!isConfigShape(body)) {
|
|
117
|
-
throw new CliError('SERVER_NOT_RECOGNIZED', `process at ${baseUrl} is not a claude4spec server (unexpected GET /api/config shape)`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function isConfigShape(body) {
|
|
121
|
-
if (!body || typeof body !== 'object')
|
|
122
|
-
return false;
|
|
123
|
-
const c = body;
|
|
124
|
-
return (typeof c.name === 'string' &&
|
|
125
|
-
typeof c.port === 'number' &&
|
|
126
|
-
typeof c.pagesDir === 'string' &&
|
|
127
|
-
typeof c.mode === 'string' &&
|
|
128
|
-
'writingStyle' in c &&
|
|
129
|
-
!!c.onboarding &&
|
|
130
|
-
typeof c.onboarding === 'object');
|
|
131
|
-
}
|
|
132
|
-
/** POST JSON; przy nie-2xx propaguje `{ error: { code, message } }` endpointu. */
|
|
133
|
-
async function postJson(url, payload) {
|
|
134
|
-
let res;
|
|
135
|
-
try {
|
|
136
|
-
res = await fetch(url, {
|
|
137
|
-
method: 'POST',
|
|
138
|
-
headers: { 'content-type': 'application/json' },
|
|
139
|
-
body: JSON.stringify(payload),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
throw new CliError('SERVER_NOT_RUNNING', `request to ${url} failed (connection refused)`);
|
|
144
|
-
}
|
|
145
|
-
let body = {};
|
|
146
|
-
try {
|
|
147
|
-
body = (await res.json());
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
/* puste/nie-JSON body — obsluzone nizej przez !res.ok */
|
|
151
|
-
}
|
|
152
|
-
if (!res.ok) {
|
|
153
|
-
const err = (body.error ?? {});
|
|
154
|
-
throw new CliError(err.code ?? 'AGENT_ERROR', err.message ?? `request to ${url} failed with HTTP ${res.status}`);
|
|
155
|
-
}
|
|
156
|
-
// create-thread zwraca `{ data: {...} }`; run-turn zwraca obiekt wprost.
|
|
157
|
-
return body.data ?? body;
|
|
158
|
-
}
|
|
159
|
-
function pickThreadId(created) {
|
|
160
|
-
// `POST /api/threads` → `{ id }`; `POST /api/briefs/.../threads` → `{ threadId }`.
|
|
161
|
-
const id = created.threadId ?? created.id;
|
|
162
|
-
if (typeof id !== 'string' || !id) {
|
|
163
|
-
throw new CliError('AGENT_ERROR', 'create-thread response had no thread id');
|
|
68
|
+
process.stdout.write(JSON.stringify({ threadId: result.threadId, answer: result.answer }, null, 2) + '\n');
|
|
164
69
|
}
|
|
165
|
-
return id;
|
|
166
70
|
}
|
|
71
|
+
// Eksport pod historyczna nazwa — `src/bin/c4s.ts` importuje `runAsk`.
|
|
72
|
+
export { runAsk_cli as runAsk };
|
|
167
73
|
//# sourceMappingURL=ask.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../../src/bin/c4s/commands/ask.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../../src/bin/c4s/commands/ask.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a0 as ln,a1 as an,a2 as H,a3 as q,a4 as B,a5 as un,a6 as y,a7 as tn,a8 as L,a9 as _,aa as rn,ab as o,ac as on,ad as sn,ae as fn}from"./mermaid.core-
|
|
1
|
+
import{a0 as ln,a1 as an,a2 as H,a3 as q,a4 as B,a5 as un,a6 as y,a7 as tn,a8 as L,a9 as _,aa as rn,ab as o,ac as on,ad as sn,ae as fn}from"./mermaid.core-Dwygsmt4.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(on(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,F=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<an)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(fn((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|