@spekn/cli 1.0.2 → 1.0.3
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/dist/main.js
CHANGED
|
@@ -7305,6 +7305,8 @@ var require_BridgeDevice = __commonJS({
|
|
|
7305
7305
|
lastBridgeVersion;
|
|
7306
7306
|
/** Last time the device was seen online (heartbeat). */
|
|
7307
7307
|
lastSeenAt;
|
|
7308
|
+
/** Local HTTP port the bridge is listening on, reported during WS auth. */
|
|
7309
|
+
localPort;
|
|
7308
7310
|
metadata;
|
|
7309
7311
|
createdAt;
|
|
7310
7312
|
updatedAt;
|
|
@@ -7361,6 +7363,12 @@ var require_BridgeDevice = __commonJS({
|
|
|
7361
7363
|
}),
|
|
7362
7364
|
__metadata("design:type", Object)
|
|
7363
7365
|
], BridgeDevice.prototype, "lastSeenAt", void 0);
|
|
7366
|
+
__decorate([
|
|
7367
|
+
(0, typeorm_1.Column)("integer", {
|
|
7368
|
+
nullable: true
|
|
7369
|
+
}),
|
|
7370
|
+
__metadata("design:type", Object)
|
|
7371
|
+
], BridgeDevice.prototype, "localPort", void 0);
|
|
7364
7372
|
__decorate([
|
|
7365
7373
|
(0, typeorm_1.Column)("jsonb", {
|
|
7366
7374
|
nullable: true
|
|
@@ -81115,6 +81123,25 @@ __export(export_exports, {
|
|
|
81115
81123
|
parseArgs: () => parseArgs7,
|
|
81116
81124
|
runExportCli: () => runExportCli
|
|
81117
81125
|
});
|
|
81126
|
+
function mergeJsonConfig(existingContent, newContent) {
|
|
81127
|
+
try {
|
|
81128
|
+
const existing = JSON.parse(existingContent);
|
|
81129
|
+
const incoming = JSON.parse(newContent);
|
|
81130
|
+
for (const [key, value] of Object.entries(incoming)) {
|
|
81131
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof existing[key] === "object" && existing[key] !== null && !Array.isArray(existing[key])) {
|
|
81132
|
+
existing[key] = {
|
|
81133
|
+
...existing[key],
|
|
81134
|
+
...value
|
|
81135
|
+
};
|
|
81136
|
+
} else {
|
|
81137
|
+
existing[key] = value;
|
|
81138
|
+
}
|
|
81139
|
+
}
|
|
81140
|
+
return JSON.stringify(existing, null, 2) + "\n";
|
|
81141
|
+
} catch {
|
|
81142
|
+
return newContent;
|
|
81143
|
+
}
|
|
81144
|
+
}
|
|
81118
81145
|
function normalizeTrpcUrl(apiUrl) {
|
|
81119
81146
|
if (apiUrl.endsWith("/trpc")) {
|
|
81120
81147
|
return apiUrl;
|
|
@@ -81554,7 +81581,7 @@ async function main7() {
|
|
|
81554
81581
|
const exitCode = await runExportCli(process.argv.slice(2));
|
|
81555
81582
|
process.exit(exitCode);
|
|
81556
81583
|
}
|
|
81557
|
-
var fs7, path7, defaultDeps;
|
|
81584
|
+
var fs7, path7, MERGEABLE_CONFIG_FILES, defaultDeps;
|
|
81558
81585
|
var init_export = __esm({
|
|
81559
81586
|
"src/commands/export.ts"() {
|
|
81560
81587
|
"use strict";
|
|
@@ -81564,6 +81591,12 @@ var init_export = __esm({
|
|
|
81564
81591
|
init_credentials_store();
|
|
81565
81592
|
init_project_context();
|
|
81566
81593
|
init_structured_log();
|
|
81594
|
+
MERGEABLE_CONFIG_FILES = /* @__PURE__ */ new Set([
|
|
81595
|
+
".mcp.json",
|
|
81596
|
+
".gemini/settings.json",
|
|
81597
|
+
"opencode.jsonc"
|
|
81598
|
+
]);
|
|
81599
|
+
__name(mergeJsonConfig, "mergeJsonConfig");
|
|
81567
81600
|
defaultDeps = {
|
|
81568
81601
|
createClient: /* @__PURE__ */ __name((apiUrl, organizationId, authToken) => createTRPCProxyClient({
|
|
81569
81602
|
links: [
|
|
@@ -81581,6 +81614,14 @@ var init_export = __esm({
|
|
|
81581
81614
|
fs7.mkdirSync(dir, {
|
|
81582
81615
|
recursive: true
|
|
81583
81616
|
});
|
|
81617
|
+
const relativePath = path7.relative(process.cwd(), filePath);
|
|
81618
|
+
const normalizedRelative = relativePath.replace(/\\/g, "/");
|
|
81619
|
+
if (MERGEABLE_CONFIG_FILES.has(normalizedRelative) && fs7.existsSync(filePath)) {
|
|
81620
|
+
const existingContent = fs7.readFileSync(filePath, "utf-8");
|
|
81621
|
+
const merged = mergeJsonConfig(existingContent, content);
|
|
81622
|
+
fs7.writeFileSync(filePath, merged, "utf-8");
|
|
81623
|
+
return;
|
|
81624
|
+
}
|
|
81584
81625
|
fs7.writeFileSync(filePath, content, "utf-8");
|
|
81585
81626
|
}, "writeFile"),
|
|
81586
81627
|
stdout: /* @__PURE__ */ __name((content) => process.stdout.write(content), "stdout"),
|
|
@@ -112478,7 +112519,8 @@ AI enhancement skipped: ${aiResult.error}
|
|
|
112478
112519
|
const payload = {
|
|
112479
112520
|
deviceId: pairing.deviceId,
|
|
112480
112521
|
credential: pairing.credential,
|
|
112481
|
-
bridgeVersion: BRIDGE_VERSION2
|
|
112522
|
+
bridgeVersion: BRIDGE_VERSION2,
|
|
112523
|
+
port: this.config.get().port
|
|
112482
112524
|
};
|
|
112483
112525
|
this.send("bridge.auth", payload);
|
|
112484
112526
|
}
|
|
@@ -112490,7 +112532,8 @@ AI enhancement skipped: ${aiResult.error}
|
|
|
112490
112532
|
const payload = {
|
|
112491
112533
|
deviceId: pairing?.deviceId ?? "unknown",
|
|
112492
112534
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
112493
|
-
uptime: Math.floor((Date.now() - this.startedAt.getTime()) / 1e3)
|
|
112535
|
+
uptime: Math.floor((Date.now() - this.startedAt.getTime()) / 1e3),
|
|
112536
|
+
port: this.config.get().port
|
|
112494
112537
|
};
|
|
112495
112538
|
this.send("bridge.heartbeat", payload);
|
|
112496
112539
|
this.ws.ping();
|
|
@@ -123312,7 +123355,7 @@ function registerVoidAction(command, pathSegments, runner) {
|
|
|
123312
123355
|
});
|
|
123313
123356
|
}
|
|
123314
123357
|
__name(registerVoidAction, "registerVoidAction");
|
|
123315
|
-
var cliVersion = true ? "1.0.
|
|
123358
|
+
var cliVersion = true ? "1.0.3" : "0.0.0-dev";
|
|
123316
123359
|
checkForUpdates(cliVersion);
|
|
123317
123360
|
var program = new import_commander.Command();
|
|
123318
123361
|
program.name("spekn").description("Spekn CLI \u2014 Spec-Driven Development toolchain").version(cliVersion);
|
package/dist/tui/index.mjs
CHANGED
|
@@ -4267,10 +4267,10 @@ var COMMAND_CATALOG = [
|
|
|
4267
4267
|
|
|
4268
4268
|
// src/utils/build-info.ts
|
|
4269
4269
|
var BUILD_INFO = {
|
|
4270
|
-
version: "1.0.
|
|
4270
|
+
version: "1.0.3",
|
|
4271
4271
|
gitCommit: "29a1c38",
|
|
4272
4272
|
gitBranch: "main",
|
|
4273
|
-
buildTime: "2026-03-
|
|
4273
|
+
buildTime: "2026-03-05T07:30:07.736Z",
|
|
4274
4274
|
nodeVersion: process.version
|
|
4275
4275
|
};
|
|
4276
4276
|
|
|
@@ -28,8 +28,8 @@ Call these MCP prompts for detailed guidance:
|
|
|
28
28
|
1. Analyze the user's request (1-2 sentences)
|
|
29
29
|
2. Confirm spec type (capability, architectural, workflow, operational, decision, intent)
|
|
30
30
|
3. Confirm spec depth (memo, standard, full)
|
|
31
|
-
4. Gather requirements — batch related questions (2-4 per interaction). Allow multiple selections where appropriate.
|
|
32
|
-
5. Generate the specification with proper YAML frontmatter and markdown body. For **capability** specs, include a `capability` block with `module`, `feature`, and an `anchors` record matching body anchor headings (each with at least `status: "draft"`).
|
|
31
|
+
4. Gather requirements — batch related questions (2-4 per interaction). Allow multiple selections where appropriate. For standard/full depth, ask about related specs (dependsOn, compatibleWith).
|
|
32
|
+
5. Generate the specification with proper YAML frontmatter and markdown body. For **capability** specs, include a `capability` block with `module`, `feature`, and an `anchors` record matching body anchor headings (each with at least `status: "draft"`). **Populate relationship fields** (`dependsOn`, `compatibleWith`, `extends`, `conflictsWith`) based on user answers or inferred from context.
|
|
33
33
|
6. Present the full specification content as your final response
|
|
34
34
|
|
|
35
35
|
Execute ALL workflow steps in a SINGLE turn when possible. After each interaction response, immediately proceed to the next step. The user should not need to type "continue".
|
|
@@ -32,6 +32,15 @@ If the spec's frontmatter is missing `hints` (constraints, requirements, technic
|
|
|
32
32
|
- `hints.technical` from technical context sections
|
|
33
33
|
- `aiContext.priorityAnchors` from the most critical anchor paths (max 5)
|
|
34
34
|
|
|
35
|
+
## Relationship Enrichment
|
|
36
|
+
|
|
37
|
+
If the spec's frontmatter is missing relationships (`dependsOn`, `extends`, `compatibleWith`, `conflictsWith`):
|
|
38
|
+
- Use `spekn_spec_list` or `spekn_spec_search` to find related specs in the same project
|
|
39
|
+
- Propose `dependsOn` for specs this one requires or references
|
|
40
|
+
- Propose `compatibleWith` for specs in the same domain/module (matching first anchor segment)
|
|
41
|
+
- Propose `conflictsWith` if overlapping or contradictory requirements exist
|
|
42
|
+
- Relationships are worth +4 points in the frontmatter scoring category
|
|
43
|
+
|
|
35
44
|
## Capability Block Enrichment
|
|
36
45
|
|
|
37
46
|
For **capability** specs, check whether the `capability` frontmatter block is present and complete:
|