heyspex 0.2.2 → 0.2.4
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/marketplace.json +2 -1
- package/README.md +11 -0
- package/bin/hs-vault-binding.mjs +157 -0
- package/bin/hs.mjs +83 -79
- package/bin/spexcode.mjs +91 -0
- package/dev-factory/engine/worktree.mjs +36 -7
- package/dev-factory/lib/epic-detect.mjs +2 -2
- package/dev-factory/lib/fleet-readiness.mjs +3 -5
- package/dev-factory/lib/fleet-state.mjs +2 -2
- package/dev-factory/lib/sufficiency-score.mjs +3 -5
- package/dist/cli/hs-check.mjs +76 -46
- package/dist/cli/hs-claim.mjs +63 -33
- package/dist/cli/hs-connect.mjs +520 -214
- package/dist/cli/hs-defer.mjs +161 -19
- package/dist/cli/hs-dev.mjs +11 -5
- package/dist/cli/hs-env.mjs +187 -161
- package/dist/cli/hs-index-rebuild.mjs +123 -78
- package/dist/cli/hs-index-reconcile.mjs +203 -107
- package/dist/cli/hs-init.mjs +426 -179
- package/dist/cli/hs-install.mjs +759 -437
- package/dist/cli/hs-join.mjs +590 -383
- package/dist/cli/hs-vault-pull.mjs +359 -254
- package/dist/cli/hs-vault-push.mjs +151 -113
- package/dist/cli/hs-vault.mjs +271 -104
- package/dist/cli/hs-workspace.mjs +90 -57
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +178 -91
- package/docs/copilot-plugin-install.md +200 -177
- package/docs/driving-heyspex-from-copilot.md +174 -165
- package/docs/mcp-client-config.md +93 -25
- package/package.json +257 -250
- package/plugins/heyspex/.claude-plugin/plugin.json +13 -12
- package/plugins/heyspex/.cursor-plugin/plugin.json +16 -15
- package/plugins/heyspex/.mcp.json +3 -4
- package/plugins/heyspex/README.md +323 -312
- package/plugins/heyspex/assets/heyspex-glyph-128.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph-256.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph.svg +12 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +21 -7
- package/plugins/heyspex/mcp.json +12 -13
- package/scripts/check-mcp-freshness.mjs +6 -4
- package/scripts/claude-hooks/_intent-classifier-router.mjs +518 -456
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +305 -279
- package/scripts/claude-hooks/research-method-guard.mjs +2 -2
- package/scripts/claude-hooks/wip-checkpoint.mjs +33 -9
- package/scripts/claude-statusline/fonts/HeySpexIcons.ttf +0 -0
- package/scripts/claude-statusline/statusline-command.mjs +1073 -0
- package/scripts/copilot-statusline.mjs +130 -0
- package/scripts/dev-server-status.mjs +3 -2
- package/scripts/dev-server-stop.mjs +3 -2
- package/scripts/hs-capture-cli.mjs +2 -2
- package/scripts/hs-settings.mjs +2 -2
- package/scripts/hs-view.mjs +3 -2
- package/scripts/install-copilot-hooks.mjs +152 -36
- package/scripts/lib/copilot-cli.mjs +108 -0
- package/scripts/lib/customer-kit.mjs +223 -30
- package/scripts/lib/dev-mode.mjs +28 -2
- package/scripts/lib/shared-path-helpers.mjs +32 -0
- package/scripts/lib/standalone-doctor.mjs +131 -32
- package/scripts/wip-ledger-health.mjs +3 -2
- package/spexharness/src/gates/vault-mirror-catchup.mjs +113 -24
- package/spexharness/src/gates/vault-mirror-catchup.runner.mjs +52 -0
- package/spexharness/src/intent-directive.mjs +839 -626
- package/spexharness/src/rule-table.mjs +1 -1
- package/vendor/heyspex-mcp/cli-verbs.mjs +16 -2
- package/vendor/heyspex-mcp/cli.mjs +20 -4
- package/vendor/heyspex-mcp/console-fetch.mjs +15 -3
- package/vendor/heyspex-mcp/dev-tools.mjs +11 -4
- package/vendor/heyspex-mcp/events-tools.mjs +1 -1
- package/vendor/heyspex-mcp/factory-run-status.mjs +42 -0
- package/vendor/heyspex-mcp/http-transport.mjs +6 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +4 -2
- package/vendor/heyspex-mcp/server-identity.mjs +13 -0
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +26 -1
- package/vendor/heyspex-mcp/test-helpers.mjs +5 -2
- package/vendor/heyspex-mcp/tool-catalog.mjs +12 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +63 -23
- package/vendor/heyspex-mcp/usable-dir-env.mjs +82 -0
- package/vendor/heyspex-mcp/vault-binding.mjs +839 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +353 -245
|
@@ -124,9 +124,9 @@ function resolveBearer({ envToken, credentialsText, accountId: accountId2, legac
|
|
|
124
124
|
if (entry?.mcp_token) return { token: entry.mcp_token, source: "credentials-file" };
|
|
125
125
|
return { token: null, source: null };
|
|
126
126
|
}
|
|
127
|
-
function readTextOrNull(read,
|
|
127
|
+
function readTextOrNull(read, path5) {
|
|
128
128
|
try {
|
|
129
|
-
const raw = read(
|
|
129
|
+
const raw = read(path5);
|
|
130
130
|
return typeof raw === "string" ? raw : null;
|
|
131
131
|
} catch {
|
|
132
132
|
return null;
|
|
@@ -174,8 +174,8 @@ var init_credentials = __esm({
|
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
// scripts/lib/dev-mode.mjs
|
|
177
|
-
import { mkdirSync as
|
|
178
|
-
import { homedir as
|
|
177
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
|
|
178
|
+
import { homedir as homedir8 } from "node:os";
|
|
179
179
|
import { join as join8 } from "node:path";
|
|
180
180
|
function devModeFilePath(homeDir = heyspexHome()) {
|
|
181
181
|
return join8(homeDir, ".heyspex", DEV_MODE_FILENAME);
|
|
@@ -230,6 +230,11 @@ function readLocalDevModeRecord({ homeDir = heyspexHome(), readFile: readFile2 =
|
|
|
230
230
|
return { record: null, parseError: `unparseable dev-mode.json: ${String(err?.message ?? err)}` };
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
+
function overrideCloudCheck(source, cloudKnown, staleAgainstCloud) {
|
|
234
|
+
if (source !== "local-override") return "not-applicable";
|
|
235
|
+
if (!cloudKnown) return "unverified";
|
|
236
|
+
return staleAgainstCloud ? "stale" : "in-sync";
|
|
237
|
+
}
|
|
233
238
|
function resolveDevMode({
|
|
234
239
|
env = process.env,
|
|
235
240
|
homeDir = heyspexHome(),
|
|
@@ -269,6 +274,7 @@ function resolveDevMode({
|
|
|
269
274
|
const semantics = deriveSemantics(mode, reliance);
|
|
270
275
|
const consoleUrl = source === "local-override" && local.record?.console_url ? local.record.console_url.replace(/\/+$/, "") : semantics.consoleUrl;
|
|
271
276
|
const staleAgainstCloud = source === "local-override" && cloudValue !== null && (cloudValue.mode !== mode || mode === "dev" && cloudValue.reliance !== semantics.reliance);
|
|
277
|
+
const cloudCheck = overrideCloudCheck(source, cloudKnown, staleAgainstCloud);
|
|
272
278
|
return {
|
|
273
279
|
mode,
|
|
274
280
|
reliance: semantics.reliance,
|
|
@@ -286,7 +292,8 @@ function resolveDevMode({
|
|
|
286
292
|
present: local.record !== null,
|
|
287
293
|
record: local.record,
|
|
288
294
|
parseError: local.parseError,
|
|
289
|
-
staleAgainstCloud
|
|
295
|
+
staleAgainstCloud,
|
|
296
|
+
cloudCheck
|
|
290
297
|
},
|
|
291
298
|
cloudSetting: { known: cloudKnown, value: cloudValue }
|
|
292
299
|
};
|
|
@@ -300,7 +307,7 @@ var init_dev_mode = __esm({
|
|
|
300
307
|
CLOUD_CONSOLE_URL = "https://app.heyspex.com";
|
|
301
308
|
LOCAL_CONSOLE_URL = "http://localhost:3000";
|
|
302
309
|
DEV_MODE_FILENAME = "dev-mode.json";
|
|
303
|
-
defaultReadFile = (p) =>
|
|
310
|
+
defaultReadFile = (p) => readFileSync8(p, "utf8");
|
|
304
311
|
}
|
|
305
312
|
});
|
|
306
313
|
|
|
@@ -2053,13 +2060,13 @@ var init_postgres = __esm({
|
|
|
2053
2060
|
});
|
|
2054
2061
|
|
|
2055
2062
|
// spex-console/bin/hs-workspace.ts
|
|
2056
|
-
import { readFileSync as
|
|
2057
|
-
import
|
|
2063
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
2064
|
+
import path4 from "node:path";
|
|
2058
2065
|
import process4 from "node:process";
|
|
2059
2066
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
2060
2067
|
|
|
2061
2068
|
// spex-console/src/lib/cli/control-shared.ts
|
|
2062
|
-
import
|
|
2069
|
+
import path2 from "node:path";
|
|
2063
2070
|
|
|
2064
2071
|
// scripts/lib/hs-command.mjs
|
|
2065
2072
|
import { existsSync } from "node:fs";
|
|
@@ -2082,8 +2089,8 @@ var HS_DISPATCHER_PREFIX = HS_DISPATCHER_PATH ? `node ${shellQuote(HS_DISPATCHER
|
|
|
2082
2089
|
// vendor/heyspex-mcp/console-fetch.mjs
|
|
2083
2090
|
init_heyspex_home();
|
|
2084
2091
|
init_credentials();
|
|
2085
|
-
import { readFileSync as
|
|
2086
|
-
import { homedir as
|
|
2092
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
2093
|
+
import { homedir as homedir6 } from "node:os";
|
|
2087
2094
|
import { join as join6 } from "node:path";
|
|
2088
2095
|
|
|
2089
2096
|
// vendor/heyspex-mcp/session-owner.mjs
|
|
@@ -2108,14 +2115,14 @@ var VAULT_LESS_ENDPOINTS = Object.freeze([
|
|
|
2108
2115
|
"GET /api/workspaces",
|
|
2109
2116
|
"* /api/admin/dev-mode"
|
|
2110
2117
|
]);
|
|
2111
|
-
function pathnameOf(
|
|
2112
|
-
const raw = String(
|
|
2118
|
+
function pathnameOf(path5) {
|
|
2119
|
+
const raw = String(path5 ?? "").split("?")[0].split("#")[0];
|
|
2113
2120
|
const noTrailing = raw.length > 1 ? raw.replace(/\/+$/, "") : raw;
|
|
2114
2121
|
return noTrailing || "/";
|
|
2115
2122
|
}
|
|
2116
|
-
function isVaultLessEndpoint(method,
|
|
2123
|
+
function isVaultLessEndpoint(method, path5) {
|
|
2117
2124
|
const m = String(method || "GET").toUpperCase();
|
|
2118
|
-
const pathname = pathnameOf(
|
|
2125
|
+
const pathname = pathnameOf(path5);
|
|
2119
2126
|
return VAULT_LESS_ENDPOINTS.some((row) => {
|
|
2120
2127
|
const [rowMethod, rowPath] = row.split(" ");
|
|
2121
2128
|
return rowPath === pathname && (rowMethod === "*" || rowMethod === m);
|
|
@@ -2135,7 +2142,9 @@ import {
|
|
|
2135
2142
|
import { basename, join as join4, isAbsolute as isAbsolute2 } from "node:path";
|
|
2136
2143
|
|
|
2137
2144
|
// scripts/lib/shared-path-helpers.mjs
|
|
2145
|
+
import { realpathSync } from "node:fs";
|
|
2138
2146
|
import { isAbsolute, resolve as resolve2, sep } from "node:path";
|
|
2147
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2139
2148
|
function resolveCodeRoot({
|
|
2140
2149
|
explicit,
|
|
2141
2150
|
packageRoot,
|
|
@@ -2154,9 +2163,30 @@ function resolveCodeRoot({
|
|
|
2154
2163
|
|
|
2155
2164
|
// vendor/heyspex-mcp/vault-resolve.mjs
|
|
2156
2165
|
init_heyspex_home();
|
|
2157
|
-
import { existsSync as
|
|
2158
|
-
import { homedir as
|
|
2159
|
-
|
|
2166
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
|
|
2167
|
+
import { homedir as homedir5, tmpdir } from "node:os";
|
|
2168
|
+
|
|
2169
|
+
// vendor/heyspex-mcp/usable-dir-env.mjs
|
|
2170
|
+
import { statSync } from "node:fs";
|
|
2171
|
+
import { isAbsolute as isAbsolute3 } from "node:path";
|
|
2172
|
+
|
|
2173
|
+
// vendor/heyspex-mcp/vault-resolve.mjs
|
|
2174
|
+
import { basename as basename2, dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
|
|
2175
|
+
|
|
2176
|
+
// vendor/heyspex-mcp/vault-binding.mjs
|
|
2177
|
+
import {
|
|
2178
|
+
copyFileSync,
|
|
2179
|
+
existsSync as existsSync3,
|
|
2180
|
+
mkdirSync as mkdirSync3,
|
|
2181
|
+
readFileSync as readFileSync4,
|
|
2182
|
+
realpathSync as realpathSync2,
|
|
2183
|
+
renameSync as renameSync3,
|
|
2184
|
+
statSync as statSync2,
|
|
2185
|
+
unlinkSync,
|
|
2186
|
+
writeFileSync as writeFileSync3
|
|
2187
|
+
} from "node:fs";
|
|
2188
|
+
import { homedir as homedir4 } from "node:os";
|
|
2189
|
+
import path from "node:path";
|
|
2160
2190
|
|
|
2161
2191
|
// vendor/heyspex-mcp/console-fetch.mjs
|
|
2162
2192
|
var SCOPE_REFUSAL_CODES = Object.freeze(["VAULT_SCOPE_MISMATCH", "ACCOUNT_MISMATCH", "VAULT_NOT_REGISTERED"]);
|
|
@@ -2165,17 +2195,17 @@ var SCOPE_REFUSAL_CODES = Object.freeze(["VAULT_SCOPE_MISMATCH", "ACCOUNT_MISMAT
|
|
|
2165
2195
|
init_credentials();
|
|
2166
2196
|
|
|
2167
2197
|
// spex-console/src/lib/vault-registry/registry-file.ts
|
|
2168
|
-
import { existsSync as
|
|
2198
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2169
2199
|
import { dirname as dirname4, join as join7, resolve as resolve4 } from "node:path";
|
|
2170
2200
|
|
|
2171
2201
|
// spex-console/src/lib/heyspex-home.ts
|
|
2172
|
-
import { homedir as
|
|
2202
|
+
import { homedir as homedir7 } from "node:os";
|
|
2173
2203
|
function heyspexHome2(env = process.env) {
|
|
2174
2204
|
const override = env?.HEYSPEX_HOME;
|
|
2175
2205
|
if (typeof override === "string" && override.trim().length > 0) {
|
|
2176
2206
|
return override.trim();
|
|
2177
2207
|
}
|
|
2178
|
-
return
|
|
2208
|
+
return homedir7();
|
|
2179
2209
|
}
|
|
2180
2210
|
|
|
2181
2211
|
// spex-console/src/lib/vault-registry/types.ts
|
|
@@ -2297,9 +2327,9 @@ function parseVaultRegistryFile(json) {
|
|
|
2297
2327
|
}
|
|
2298
2328
|
function readRegistryJson(opts) {
|
|
2299
2329
|
const filePath = vaultRegistryFilePath(opts);
|
|
2300
|
-
if (!
|
|
2330
|
+
if (!existsSync5(filePath)) return { kind: "missing" };
|
|
2301
2331
|
try {
|
|
2302
|
-
const raw =
|
|
2332
|
+
const raw = readFileSync7(filePath, "utf8");
|
|
2303
2333
|
const json = JSON.parse(raw);
|
|
2304
2334
|
if (registryFileSchemaOf(json) === null) return { kind: "unreadable" };
|
|
2305
2335
|
return { kind: "ok", raw, json };
|
|
@@ -2369,10 +2399,10 @@ function assertNotRealHomeRegistryUnderTest(filePath) {
|
|
|
2369
2399
|
function writeVaultRegistry(registry, opts = {}) {
|
|
2370
2400
|
const filePath = vaultRegistryFilePath(opts);
|
|
2371
2401
|
assertNotRealHomeRegistryUnderTest(filePath);
|
|
2372
|
-
|
|
2402
|
+
mkdirSync4(dirname4(filePath), { recursive: true });
|
|
2373
2403
|
const tmpPath = `${filePath}.tmp`;
|
|
2374
|
-
|
|
2375
|
-
|
|
2404
|
+
writeFileSync4(tmpPath, serializeVaultRegistry(registry), "utf8");
|
|
2405
|
+
renameSync4(tmpPath, filePath);
|
|
2376
2406
|
}
|
|
2377
2407
|
function isValidId(id) {
|
|
2378
2408
|
if (!isNonEmptyString(id)) return false;
|
|
@@ -2536,11 +2566,11 @@ function readPairedBearer(opts = {}) {
|
|
|
2536
2566
|
function readPairedToken(opts = {}) {
|
|
2537
2567
|
return readPairedBearer(opts).token ?? void 0;
|
|
2538
2568
|
}
|
|
2539
|
-
function scopeHeadersFor(scope, method,
|
|
2569
|
+
function scopeHeadersFor(scope, method, path5) {
|
|
2540
2570
|
if (scope === "none") {
|
|
2541
|
-
if (!isVaultLessEndpoint(method,
|
|
2571
|
+
if (!isVaultLessEndpoint(method, path5)) {
|
|
2542
2572
|
throw new Error(
|
|
2543
|
-
`controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${
|
|
2573
|
+
`controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${path5} is vault-scoped and must name { accountId, vaultId }.`
|
|
2544
2574
|
);
|
|
2545
2575
|
}
|
|
2546
2576
|
return {};
|
|
@@ -2551,7 +2581,7 @@ function cloudRequestScope(scope) {
|
|
|
2551
2581
|
const named = { accountId: scope.accountId, vaultId: scope.vaultId };
|
|
2552
2582
|
return {
|
|
2553
2583
|
...named,
|
|
2554
|
-
headersFor: (method,
|
|
2584
|
+
headersFor: (method, path5) => isVaultLessEndpoint(method, path5) ? {} : scopeHeadersFor(named, method, path5)
|
|
2555
2585
|
};
|
|
2556
2586
|
}
|
|
2557
2587
|
function withCloudScope(deps, accountId2, vaultId) {
|
|
@@ -2562,8 +2592,8 @@ function withCloudScope(deps, accountId2, vaultId) {
|
|
|
2562
2592
|
// scripts/lib/console-url-resolver.mjs
|
|
2563
2593
|
init_heyspex_home();
|
|
2564
2594
|
init_dev_mode();
|
|
2565
|
-
import { readFileSync as
|
|
2566
|
-
import { homedir as
|
|
2595
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
2596
|
+
import { homedir as homedir9 } from "node:os";
|
|
2567
2597
|
import { join as join9 } from "node:path";
|
|
2568
2598
|
var DEFAULT_CONSOLE_URL = LOCAL_CONSOLE_URL;
|
|
2569
2599
|
function trimTrailingSlash(url) {
|
|
@@ -2601,7 +2631,7 @@ function readCredentialsConsoleUrl({ homeDir = heyspexHome(), readFile: readFile
|
|
|
2601
2631
|
}
|
|
2602
2632
|
}
|
|
2603
2633
|
function defaultReadFile2(p) {
|
|
2604
|
-
return
|
|
2634
|
+
return readFileSync9(p, "utf8");
|
|
2605
2635
|
}
|
|
2606
2636
|
function readDiscoveryFileConsoleUrl(repoRoot, { readDiscovery = defaultReadFile2 } = {}) {
|
|
2607
2637
|
if (!repoRoot) return null;
|
|
@@ -2699,7 +2729,7 @@ var HELP = [
|
|
|
2699
2729
|
|
|
2700
2730
|
// spex-console/src/lib/cli/install-identity.ts
|
|
2701
2731
|
import { spawnSync } from "node:child_process";
|
|
2702
|
-
import { existsSync as
|
|
2732
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
2703
2733
|
import { join as join10 } from "node:path";
|
|
2704
2734
|
import { createInterface } from "node:readline/promises";
|
|
2705
2735
|
init_credentials();
|
|
@@ -2707,7 +2737,7 @@ init_credentials();
|
|
|
2707
2737
|
// vendor/heyspex-mcp/whoami.mjs
|
|
2708
2738
|
init_heyspex_home();
|
|
2709
2739
|
init_credentials();
|
|
2710
|
-
import { homedir as
|
|
2740
|
+
import { homedir as homedir10 } from "node:os";
|
|
2711
2741
|
var SESSION_PATH = "/api/mcp/session";
|
|
2712
2742
|
async function probeCredentialIdentity({ consoleUrl, token, fetchImpl = fetch } = {}) {
|
|
2713
2743
|
if (!token) return { kind: "no_credential" };
|
|
@@ -2775,12 +2805,15 @@ var HELP2 = [
|
|
|
2775
2805
|
"(spex-console/src/lib/cli/template-manifest.ts) \u2014 universal docs",
|
|
2776
2806
|
"copied verbatim, template-shape docs written as author-prompt skeletons \u2014",
|
|
2777
2807
|
"plus a generated CLAUDE.md, the kept-principles index, and the template_version",
|
|
2778
|
-
"pin; with --git, one initial `git init` + commit.
|
|
2779
|
-
"holds heyspex.yaml
|
|
2780
|
-
"
|
|
2781
|
-
"
|
|
2782
|
-
"
|
|
2783
|
-
"
|
|
2808
|
+
"pin; with --git, one initial `git init` + commit. On an EXISTING vault (<dir>",
|
|
2809
|
+
"holds heyspex.yaml with a vault_id) it is a REFRESH \u2014 the repair `hs doctor`'s",
|
|
2810
|
+
"vault-template row names: only missing shipped files are added, template_version",
|
|
2811
|
+
"is written/updated in heyspex.yaml (every other byte and the vault_id kept),",
|
|
2812
|
+
"nothing existing is ever overwritten (an existing CLAUDE.md gets a",
|
|
2813
|
+
"CLAUDE.md.template beside it), the result lists each manifest row as created or",
|
|
2814
|
+
"kept, and a second run writes nothing. <dir> may be any path (a satellite repo",
|
|
2815
|
+
"names its vault, e.g. `hs init --customer-vault ../my-specs`). Refuses only a",
|
|
2816
|
+
"non-empty <dir> that has no heyspex.yaml. See init.customer-vault.ts.",
|
|
2784
2817
|
"",
|
|
2785
2818
|
"Flags:",
|
|
2786
2819
|
" --console-url <url> console_url value (default: the mode-aware console --",
|
|
@@ -3048,7 +3081,7 @@ function isInteractiveTerminal() {
|
|
|
3048
3081
|
}
|
|
3049
3082
|
function defaultIdentityGateIo(opts) {
|
|
3050
3083
|
const consoleUrl = opts.consoleUrl.trim().replace(/\/+$/, "");
|
|
3051
|
-
const loginCli = [opts.platformRoot, resolveCodeRoot({})].filter((r) => Boolean(r && r.trim())).map((r) => join10(r, "vendor", "heyspex-mcp", "cli.mjs")).find((p) =>
|
|
3084
|
+
const loginCli = [opts.platformRoot, resolveCodeRoot({})].filter((r) => Boolean(r && r.trim())).map((r) => join10(r, "vendor", "heyspex-mcp", "cli.mjs")).find((p) => existsSync6(p));
|
|
3052
3085
|
return {
|
|
3053
3086
|
consoleUrl,
|
|
3054
3087
|
interactive: opts.interactive ?? isInteractiveTerminal(),
|
|
@@ -3096,7 +3129,7 @@ function defaultIdentityGateIo(opts) {
|
|
|
3096
3129
|
init_sql_orm_inert_cli_shim();
|
|
3097
3130
|
|
|
3098
3131
|
// spex-console/src/lib/cli/vault-workspace-shared.ts
|
|
3099
|
-
import { readFileSync as
|
|
3132
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
3100
3133
|
|
|
3101
3134
|
// spex-console/src/lib/cli/default-workspace.ts
|
|
3102
3135
|
function defaultWorkspaceId(accountId2) {
|
|
@@ -3109,7 +3142,7 @@ function resolveConfiguredAccountId(opts = {}) {
|
|
|
3109
3142
|
return resolveSessionOwnerUncached({
|
|
3110
3143
|
env: opts.env ?? process.env,
|
|
3111
3144
|
homeDir: opts.homeDir ?? heyspexHome2(),
|
|
3112
|
-
readFile: opts.readFile ?? ((p) =>
|
|
3145
|
+
readFile: opts.readFile ?? ((p) => readFileSync10(p, "utf-8"))
|
|
3113
3146
|
});
|
|
3114
3147
|
}
|
|
3115
3148
|
var CLOUD_ACCOUNT_ID_REQUIRED_MESSAGE = "refusing -- no signed-in account (no HS_ACCOUNT_ID env var, and no account_id: in ~/.heyspex/config.yaml). Run `hs login` first; nothing was written.";
|
|
@@ -3130,10 +3163,10 @@ function classifyHttpFailureReason(res) {
|
|
|
3130
3163
|
if (res.status === 401) return "unauthorized";
|
|
3131
3164
|
return "server-error";
|
|
3132
3165
|
}
|
|
3133
|
-
async function cloudHttpRequest(http, method,
|
|
3134
|
-
const scopeHeaders = http.scope ? http.scope.headersFor(method,
|
|
3166
|
+
async function cloudHttpRequest(http, method, path5, body) {
|
|
3167
|
+
const scopeHeaders = http.scope ? http.scope.headersFor(method, path5) : {};
|
|
3135
3168
|
try {
|
|
3136
|
-
const res = await http.fetchImpl(`${http.consoleUrl}${
|
|
3169
|
+
const res = await http.fetchImpl(`${http.consoleUrl}${path5}`, {
|
|
3137
3170
|
method,
|
|
3138
3171
|
headers: {
|
|
3139
3172
|
"content-type": "application/json",
|
|
@@ -3186,8 +3219,8 @@ async function classifyWorkspaceConflictHttp(id, conflictJson, http) {
|
|
|
3186
3219
|
if (!Array.isArray(rows)) return { written: false, reason: "server-error" };
|
|
3187
3220
|
return rows.some((w) => w.id === id) ? { written: true } : { written: false, reason: "owned-by-other-account" };
|
|
3188
3221
|
}
|
|
3189
|
-
async function mutateHttp(http, method,
|
|
3190
|
-
const res = await cloudHttpRequest(http, method,
|
|
3222
|
+
async function mutateHttp(http, method, path5, body, landed) {
|
|
3223
|
+
const res = await cloudHttpRequest(http, method, path5, body);
|
|
3191
3224
|
if (res.ok) return landed;
|
|
3192
3225
|
if (res.status === 404) return "not_found";
|
|
3193
3226
|
if (res.status === 403 && isOwnedByOtherAccountCode(errorCodeOf(res.json))) {
|
|
@@ -3436,7 +3469,7 @@ init_postgres_client_cli_shim();
|
|
|
3436
3469
|
init_postgres();
|
|
3437
3470
|
|
|
3438
3471
|
// spex-console/src/lib/vault-registry/repo-identity.ts
|
|
3439
|
-
import
|
|
3472
|
+
import path3 from "node:path";
|
|
3440
3473
|
|
|
3441
3474
|
// spex-console/src/lib/vault-registry/vault-workspace-store.ts
|
|
3442
3475
|
function mapProbeFailureReason(reason) {
|
|
@@ -3778,7 +3811,7 @@ function buildCloseNotDestroyConfirm(kind, verb, displayName) {
|
|
|
3778
3811
|
}
|
|
3779
3812
|
|
|
3780
3813
|
// spex-console/src/lib/vault-registry/list.ts
|
|
3781
|
-
import { existsSync as
|
|
3814
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
3782
3815
|
function pointerDeps2(deps) {
|
|
3783
3816
|
return deps.accountPointer ?? { registryOpts: deps.registryOpts };
|
|
3784
3817
|
}
|
|
@@ -4299,11 +4332,11 @@ function readLocalReceiptSide(subject, registryOpts = {}) {
|
|
|
4299
4332
|
return unreadSide(`registry.json could not be read: ${message(err)}`);
|
|
4300
4333
|
}
|
|
4301
4334
|
}
|
|
4302
|
-
async function readList(http,
|
|
4303
|
-
const res = await cloudHttpRequest(http, "GET",
|
|
4335
|
+
async function readList(http, path5, key) {
|
|
4336
|
+
const res = await cloudHttpRequest(http, "GET", path5);
|
|
4304
4337
|
const rows = res.json?.[key];
|
|
4305
4338
|
if (!res.ok || !Array.isArray(rows)) {
|
|
4306
|
-
return { reason: `GET ${
|
|
4339
|
+
return { reason: `GET ${path5.split("?")[0]} answered HTTP ${res.status}` };
|
|
4307
4340
|
}
|
|
4308
4341
|
return { rows: rows.filter((r) => Boolean(r) && typeof r === "object") };
|
|
4309
4342
|
}
|
|
@@ -4995,7 +5028,7 @@ function runEntry(name, main2, options = {}) {
|
|
|
4995
5028
|
// spex-console/bin/hs-workspace.ts
|
|
4996
5029
|
function readFile(p) {
|
|
4997
5030
|
try {
|
|
4998
|
-
return
|
|
5031
|
+
return readFileSync11(p, "utf8");
|
|
4999
5032
|
} catch {
|
|
5000
5033
|
return null;
|
|
5001
5034
|
}
|
|
@@ -5032,14 +5065,14 @@ async function main() {
|
|
|
5032
5065
|
process4.exitCode = parsed.error.code;
|
|
5033
5066
|
return;
|
|
5034
5067
|
}
|
|
5035
|
-
const vaultRoot = process4.env.HS_VAULT_ROOT ?
|
|
5068
|
+
const vaultRoot = process4.env.HS_VAULT_ROOT ? path4.resolve(process4.env.HS_VAULT_ROOT) : process4.cwd();
|
|
5036
5069
|
const consoleUrl = resolveSpexConsoleUrl(vaultRoot, readFile);
|
|
5037
5070
|
const gate = await gateWriteVerb({
|
|
5038
5071
|
namespace: "hs workspace",
|
|
5039
5072
|
sub: parsed.args.sub,
|
|
5040
5073
|
writeVerbs: WORKSPACE_WRITE_VERBS,
|
|
5041
5074
|
flags: identityArgv.flags,
|
|
5042
|
-
io: defaultIdentityGateIo({ consoleUrl, platformRoot:
|
|
5075
|
+
io: defaultIdentityGateIo({ consoleUrl, platformRoot: path4.resolve(process4.cwd(), "..") })
|
|
5043
5076
|
});
|
|
5044
5077
|
if (gate && !gate.ok) {
|
|
5045
5078
|
process4.stderr.write(
|