@specship/specship-win32-arm64 0.21.0 → 0.21.2
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/lib/dist/bin/specship.js +169 -101
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/claudemd/audit.d.ts +41 -0
- package/lib/dist/claudemd/audit.d.ts.map +1 -0
- package/lib/dist/claudemd/audit.js +291 -0
- package/lib/dist/claudemd/audit.js.map +1 -0
- package/lib/dist/commands/specship/check.md +21 -2
- package/lib/dist/commands/specship/day.md +35 -0
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +10 -0
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +36 -0
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/installer/integration-setup.d.ts +73 -0
- package/lib/dist/installer/integration-setup.d.ts.map +1 -0
- package/lib/dist/installer/integration-setup.js +108 -0
- package/lib/dist/installer/integration-setup.js.map +1 -0
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +1 -0
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/jira/client.d.ts +3 -0
- package/lib/dist/jira/client.d.ts.map +1 -1
- package/lib/dist/jira/client.js +9 -0
- package/lib/dist/jira/client.js.map +1 -1
- package/lib/dist/mcp/jira-tools.d.ts +37 -0
- package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
- package/lib/dist/mcp/jira-tools.js +145 -2
- package/lib/dist/mcp/jira-tools.js.map +1 -1
- package/lib/dist/mcp/model-context.d.ts +11 -0
- package/lib/dist/mcp/model-context.d.ts.map +1 -1
- package/lib/dist/mcp/model-context.js +31 -0
- package/lib/dist/mcp/model-context.js.map +1 -1
- package/lib/dist/mcp/server-instructions.d.ts +1 -1
- package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
- package/lib/dist/mcp/server-instructions.js +1 -0
- package/lib/dist/mcp/server-instructions.js.map +1 -1
- package/lib/dist/mcp/tools.d.ts +7 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +60 -0
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/statusline/index.d.ts.map +1 -1
- package/lib/dist/statusline/index.js +25 -1
- package/lib/dist/statusline/index.js.map +1 -1
- package/lib/dist/statusline/render.d.ts +15 -0
- package/lib/dist/statusline/render.d.ts.map +1 -1
- package/lib/dist/statusline/render.js +19 -5
- package/lib/dist/statusline/render.js.map +1 -1
- package/lib/dist/statusline/tips.d.ts +32 -0
- package/lib/dist/statusline/tips.d.ts.map +1 -0
- package/lib/dist/statusline/tips.js +49 -0
- package/lib/dist/statusline/tips.js.map +1 -0
- package/lib/dist/taskship/detect.d.ts +35 -0
- package/lib/dist/taskship/detect.d.ts.map +1 -0
- package/lib/dist/taskship/detect.js +112 -0
- package/lib/dist/taskship/detect.js.map +1 -0
- package/lib/dist/update/updater.d.ts +7 -0
- package/lib/dist/update/updater.d.ts.map +1 -1
- package/lib/dist/update/updater.js +11 -0
- package/lib/dist/update/updater.js.map +1 -1
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +1 -1
- package/package.json +1 -1
package/lib/dist/bin/specship.js
CHANGED
|
@@ -187,7 +187,7 @@ function sniffClaudeSlugCwd(claudeRoot, slug) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
190
|
-
* Auto-pick a default project for `specship
|
|
190
|
+
* Auto-pick a default project for `specship desktop` when the user
|
|
191
191
|
* didn't pass `-p` and the cwd isn't initialized either. Walks
|
|
192
192
|
* `~/.claude/projects/*` (Claude Code's per-project transcript dirs),
|
|
193
193
|
* resolves each slug back to a real path, and returns the most-recently-
|
|
@@ -850,6 +850,18 @@ function main() {
|
|
|
850
850
|
if (drifted > 0) {
|
|
851
851
|
console.log(`⚠ ${drifted} spec link(s) drifted — review with /specship:check drifted`);
|
|
852
852
|
}
|
|
853
|
+
// CLAUDE.md governance findings ride the same SessionStart line
|
|
854
|
+
// (CLAUDEMD-DOC, REQ-CLAUDEMD-003) — silent at zero.
|
|
855
|
+
try {
|
|
856
|
+
const { readClaudeMdAudit } = require('../claudemd/audit');
|
|
857
|
+
const audit = readClaudeMdAudit(projectPath);
|
|
858
|
+
if (audit && audit.findings.length > 0) {
|
|
859
|
+
console.log(`⚠ ${audit.findings.length} CLAUDE.md finding(s) — review with /specship:check claudemd`);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
catch {
|
|
863
|
+
/* surfacing is best-effort */
|
|
864
|
+
}
|
|
853
865
|
};
|
|
854
866
|
try {
|
|
855
867
|
if (!(0, directory_1.isInitialized)(projectPath)) {
|
|
@@ -1362,7 +1374,7 @@ function main() {
|
|
|
1362
1374
|
}
|
|
1363
1375
|
if (result.empty || result.open.length === 0) {
|
|
1364
1376
|
info('No proposals yet — not enough signal in the ingested transcripts.');
|
|
1365
|
-
info('Tip: run the dashboard with `specship
|
|
1377
|
+
info('Tip: run the dashboard with `specship desktop --ingest` to build transcript history.');
|
|
1366
1378
|
cg.destroy();
|
|
1367
1379
|
return;
|
|
1368
1380
|
}
|
|
@@ -1835,119 +1847,138 @@ function main() {
|
|
|
1835
1847
|
}
|
|
1836
1848
|
});
|
|
1837
1849
|
/**
|
|
1838
|
-
* specship
|
|
1850
|
+
* `specship desktop` (DESKTOP-CMD-DOC, REQ-DESKTOP-CMD-001): boot the
|
|
1851
|
+
* in-process Fastify server + built desktop SPA, optionally also starting
|
|
1852
|
+
* MCP stdio (`--mcp`) against the resolved project. This is the behavior the
|
|
1853
|
+
* retired `serve --ui` branch carried, now under its own verb.
|
|
1839
1854
|
*/
|
|
1855
|
+
async function runDesktop(options) {
|
|
1856
|
+
const projectPath = options.path ? resolveProjectPath(options.path) : undefined;
|
|
1857
|
+
// Commander sets watch=false when --no-watch is passed. Route it through
|
|
1858
|
+
// the same env-var chokepoint the watcher and MCP server already honor.
|
|
1859
|
+
if (options.watch === false) {
|
|
1860
|
+
process.env.SPECSHIP_NO_WATCH = '1';
|
|
1861
|
+
}
|
|
1862
|
+
try {
|
|
1863
|
+
// Project root resolution:
|
|
1864
|
+
// 1. `-p <path>` if passed.
|
|
1865
|
+
// 2. The current cwd if it has been `specship init`-ed.
|
|
1866
|
+
// 3. Most-recently-touched initialized project under
|
|
1867
|
+
// ~/.claude/projects/ — so a user who runs `specship desktop`
|
|
1868
|
+
// from anywhere lands on the project they were last active in.
|
|
1869
|
+
// 4. None — server boots projectless, the desktop picker prompts
|
|
1870
|
+
// the user to choose one (analytics endpoints return 409 until
|
|
1871
|
+
// a primary exists).
|
|
1872
|
+
let root = null;
|
|
1873
|
+
if (projectPath) {
|
|
1874
|
+
root = projectPath;
|
|
1875
|
+
if (!(0, directory_1.isInitialized)(root)) {
|
|
1876
|
+
error(`SpecShip not initialized in ${root}. Run \`specship init -i\` first.`);
|
|
1877
|
+
process.exit(1);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
else if ((0, directory_1.isInitialized)(process.cwd())) {
|
|
1881
|
+
root = process.cwd();
|
|
1882
|
+
}
|
|
1883
|
+
else {
|
|
1884
|
+
root = await pickRecentInitializedProject();
|
|
1885
|
+
}
|
|
1886
|
+
const port = options.port ? parseInt(options.port, 10) : 4242;
|
|
1887
|
+
const host = options.host ?? '127.0.0.1';
|
|
1888
|
+
// Lazy-load the server package via dist path. The npm bin is
|
|
1889
|
+
// packaged with the server already built under
|
|
1890
|
+
// node_modules/@specship/specship-server, OR (dev) the
|
|
1891
|
+
// sibling server/dist directory.
|
|
1892
|
+
const { createServer } = await loadServerPackage();
|
|
1893
|
+
// The dashboard is the built desktop SPA, served in-process by the
|
|
1894
|
+
// server itself (REQ-DESKTOP-033 — the server-rendered dashboard
|
|
1895
|
+
// retired). `--no-web` opts out to run API-only.
|
|
1896
|
+
const serveUi = options.web !== false;
|
|
1897
|
+
// Resolve the SPA static dir:
|
|
1898
|
+
// - headless (--no-web): no SPA.
|
|
1899
|
+
// - otherwise the built SPA — explicit --web-dir, else auto-detect
|
|
1900
|
+
// the bundled ui/dist (webDir === undefined triggers the probe).
|
|
1901
|
+
const webDir = !serveUi ? null : (options.webDir ?? undefined);
|
|
1902
|
+
// The JSONL ingest watcher now starts in-process inside createServer
|
|
1903
|
+
// when `ingest: true`. The server owns its lifecycle; CLI just toggles.
|
|
1904
|
+
const handle = await createServer({
|
|
1905
|
+
projectRoot: root ?? undefined,
|
|
1906
|
+
host,
|
|
1907
|
+
port,
|
|
1908
|
+
ingest: options.ingest !== false,
|
|
1909
|
+
webDir,
|
|
1910
|
+
verbose: false,
|
|
1911
|
+
});
|
|
1912
|
+
console.error(chalk.bold('\nSpecShip Desktop server\n'));
|
|
1913
|
+
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ` HTTP API: ${handle.url}`);
|
|
1914
|
+
if (root) {
|
|
1915
|
+
console.error(chalk.dim(` project: ${root}`));
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
console.error(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' no primary project — pick one in the dashboard');
|
|
1919
|
+
console.error(chalk.dim(' analytics endpoints will return 409 until one is selected'));
|
|
1920
|
+
}
|
|
1921
|
+
if (serveUi) {
|
|
1922
|
+
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ` Dashboard: ${handle.url}/`);
|
|
1923
|
+
}
|
|
1924
|
+
if (options.ingest !== false) {
|
|
1925
|
+
console.error(chalk.dim(' Claude Code transcript ingest watcher active'));
|
|
1926
|
+
}
|
|
1927
|
+
if (options.mcp) {
|
|
1928
|
+
if (!root) {
|
|
1929
|
+
console.error(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' --mcp needs an initialized project — skipping MCP stdio');
|
|
1930
|
+
}
|
|
1931
|
+
else {
|
|
1932
|
+
// Also start MCP stdio in this process. The two are unrelated
|
|
1933
|
+
// surfaces hitting the same specship instance, both safe under WAL.
|
|
1934
|
+
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
1935
|
+
const mcp = new MCPServer(root);
|
|
1936
|
+
void mcp.start();
|
|
1937
|
+
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ' MCP stdio: running');
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
const shutdown = async () => {
|
|
1941
|
+
console.error(chalk.dim('shutting down…'));
|
|
1942
|
+
await handle.stop();
|
|
1943
|
+
process.exit(0);
|
|
1944
|
+
};
|
|
1945
|
+
process.on('SIGINT', () => { void shutdown(); });
|
|
1946
|
+
process.on('SIGTERM', () => { void shutdown(); });
|
|
1947
|
+
// Server now runs until terminated.
|
|
1948
|
+
}
|
|
1949
|
+
catch (err) {
|
|
1950
|
+
error(`Failed to start desktop server: ${err instanceof Error ? err.message : String(err)}`);
|
|
1951
|
+
process.exit(1);
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1840
1954
|
program
|
|
1841
1955
|
.command('serve')
|
|
1842
|
-
.description('Start SpecShip as an MCP server for AI assistants
|
|
1956
|
+
.description('Start SpecShip as an MCP server for AI assistants (stdio transport)')
|
|
1843
1957
|
.option('-p, --path <path>', 'Project path (optional for MCP mode, uses rootUri from client)')
|
|
1844
1958
|
.option('--mcp', 'Run as MCP server (stdio transport)')
|
|
1845
|
-
|
|
1846
|
-
.
|
|
1847
|
-
|
|
1848
|
-
.
|
|
1849
|
-
.
|
|
1850
|
-
.
|
|
1959
|
+
// `--ui` (and its companions) moved to `specship desktop` (DESKTOP-CMD-DOC,
|
|
1960
|
+
// REQ-DESKTOP-CMD-002). Kept as HIDDEN options so the invocation errors with
|
|
1961
|
+
// a pointer to the new command instead of commander's bare "unknown option".
|
|
1962
|
+
.addOption(new commander_1.Option('--ui', 'Moved to `specship desktop`').hideHelp())
|
|
1963
|
+
.addOption(new commander_1.Option('--port <n>', 'Moved to `specship desktop`').hideHelp())
|
|
1964
|
+
.addOption(new commander_1.Option('--host <h>', 'Moved to `specship desktop`').hideHelp())
|
|
1965
|
+
.addOption(new commander_1.Option('--ingest', 'Moved to `specship desktop`').hideHelp())
|
|
1966
|
+
.addOption(new commander_1.Option('--web-dir <path>', 'Moved to `specship desktop`').hideHelp())
|
|
1851
1967
|
.option('--no-watch', 'Disable the file watcher (no auto-sync; useful on slow filesystems like WSL2 /mnt drives)')
|
|
1852
1968
|
.action(async (options) => {
|
|
1853
1969
|
const projectPath = options.path ? resolveProjectPath(options.path) : undefined;
|
|
1970
|
+
// The dashboard moved to its own verb (REQ-DESKTOP-CMD-002.A1): fail loud
|
|
1971
|
+
// with a pointer rather than silently ignoring a UI-only flag.
|
|
1972
|
+
if (options.ui || options.port || options.host || options.ingest || options.webDir) {
|
|
1973
|
+
error('The dashboard moved to its own command. Run `specship desktop` (see `specship desktop --help`).');
|
|
1974
|
+
process.exit(1);
|
|
1975
|
+
}
|
|
1854
1976
|
// Commander sets watch=false when --no-watch is passed. Route it through
|
|
1855
1977
|
// the same env-var chokepoint the watcher and MCP server already honor.
|
|
1856
1978
|
if (options.watch === false) {
|
|
1857
1979
|
process.env.SPECSHIP_NO_WATCH = '1';
|
|
1858
1980
|
}
|
|
1859
1981
|
try {
|
|
1860
|
-
if (options.ui) {
|
|
1861
|
-
// HTTP API mode. Boots the specship server + optional JSONL
|
|
1862
|
-
// ingest watcher. Optionally also starts MCP stdio in parallel.
|
|
1863
|
-
//
|
|
1864
|
-
// Project root resolution:
|
|
1865
|
-
// 1. `-p <path>` if passed.
|
|
1866
|
-
// 2. The current cwd if it has been `specship init`-ed.
|
|
1867
|
-
// 3. Most-recently-touched initialized project under
|
|
1868
|
-
// ~/.claude/projects/ — so a user who runs `specship serve --ui`
|
|
1869
|
-
// from anywhere lands on the project they were last active in.
|
|
1870
|
-
// 4. None — server boots projectless, the desktop picker prompts
|
|
1871
|
-
// the user to choose one (analytics endpoints return 409 until
|
|
1872
|
-
// a primary exists).
|
|
1873
|
-
let root = null;
|
|
1874
|
-
if (projectPath) {
|
|
1875
|
-
root = projectPath;
|
|
1876
|
-
if (!(0, directory_1.isInitialized)(root)) {
|
|
1877
|
-
error(`SpecShip not initialized in ${root}. Run \`specship init -i\` first.`);
|
|
1878
|
-
process.exit(1);
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
else if ((0, directory_1.isInitialized)(process.cwd())) {
|
|
1882
|
-
root = process.cwd();
|
|
1883
|
-
}
|
|
1884
|
-
else {
|
|
1885
|
-
root = await pickRecentInitializedProject();
|
|
1886
|
-
}
|
|
1887
|
-
const port = options.port ? parseInt(options.port, 10) : 4242;
|
|
1888
|
-
const host = options.host ?? '127.0.0.1';
|
|
1889
|
-
// Lazy-load the server package via dist path. The npm bin is
|
|
1890
|
-
// packaged with the server already built under
|
|
1891
|
-
// node_modules/@specship/specship-server, OR (dev) the
|
|
1892
|
-
// sibling server/dist directory.
|
|
1893
|
-
const { createServer } = await loadServerPackage();
|
|
1894
|
-
// The dashboard is the built desktop SPA, served in-process by the
|
|
1895
|
-
// server itself (REQ-DESKTOP-033 — the server-rendered dashboard
|
|
1896
|
-
// retired). `--no-web` opts out to run API-only.
|
|
1897
|
-
const serveUi = options.web !== false;
|
|
1898
|
-
// Resolve the SPA static dir:
|
|
1899
|
-
// - headless (--no-web): no SPA.
|
|
1900
|
-
// - otherwise the built SPA — explicit --web-dir, else auto-detect
|
|
1901
|
-
// the bundled ui/dist (webDir === undefined triggers the probe).
|
|
1902
|
-
const webDir = !serveUi ? null : (options.webDir ?? undefined);
|
|
1903
|
-
// The JSONL ingest watcher now starts in-process inside createServer
|
|
1904
|
-
// when `ingest: true`. The server owns its lifecycle; CLI just toggles.
|
|
1905
|
-
const handle = await createServer({
|
|
1906
|
-
projectRoot: root ?? undefined,
|
|
1907
|
-
host,
|
|
1908
|
-
port,
|
|
1909
|
-
ingest: options.ingest !== false,
|
|
1910
|
-
webDir,
|
|
1911
|
-
verbose: false,
|
|
1912
|
-
});
|
|
1913
|
-
console.error(chalk.bold('\nSpecShip Desktop server\n'));
|
|
1914
|
-
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ` HTTP API: ${handle.url}`);
|
|
1915
|
-
if (root) {
|
|
1916
|
-
console.error(chalk.dim(` project: ${root}`));
|
|
1917
|
-
}
|
|
1918
|
-
else {
|
|
1919
|
-
console.error(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' no primary project — pick one in the dashboard');
|
|
1920
|
-
console.error(chalk.dim(' analytics endpoints will return 409 until one is selected'));
|
|
1921
|
-
}
|
|
1922
|
-
if (serveUi) {
|
|
1923
|
-
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ` Dashboard: ${handle.url}/`);
|
|
1924
|
-
}
|
|
1925
|
-
if (options.ingest !== false) {
|
|
1926
|
-
console.error(chalk.dim(' Claude Code transcript ingest watcher active'));
|
|
1927
|
-
}
|
|
1928
|
-
if (options.mcp) {
|
|
1929
|
-
if (!root) {
|
|
1930
|
-
console.error(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' --mcp needs an initialized project — skipping MCP stdio');
|
|
1931
|
-
}
|
|
1932
|
-
else {
|
|
1933
|
-
// Also start MCP stdio in this process. The two are unrelated
|
|
1934
|
-
// surfaces hitting the same specship instance, both safe under WAL.
|
|
1935
|
-
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
1936
|
-
const mcp = new MCPServer(root);
|
|
1937
|
-
void mcp.start();
|
|
1938
|
-
console.error(chalk.green((0, glyphs_1.getGlyphs)().ok) + ' MCP stdio: running');
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
1941
|
-
const shutdown = async () => {
|
|
1942
|
-
console.error(chalk.dim('shutting down…'));
|
|
1943
|
-
await handle.stop();
|
|
1944
|
-
process.exit(0);
|
|
1945
|
-
};
|
|
1946
|
-
process.on('SIGINT', () => { void shutdown(); });
|
|
1947
|
-
process.on('SIGTERM', () => { void shutdown(); });
|
|
1948
|
-
// Server now runs until terminated.
|
|
1949
|
-
return;
|
|
1950
|
-
}
|
|
1951
1982
|
if (options.mcp) {
|
|
1952
1983
|
// Start MCP server - it handles initialization lazily based on rootUri from client
|
|
1953
1984
|
const { MCPServer } = await Promise.resolve().then(() => __importStar(require('../mcp/index')));
|
|
@@ -1987,6 +2018,25 @@ function main() {
|
|
|
1987
2018
|
process.exit(1);
|
|
1988
2019
|
}
|
|
1989
2020
|
});
|
|
2021
|
+
/**
|
|
2022
|
+
* specship desktop (DESKTOP-CMD-DOC) — the local dashboard + HTTP API, the
|
|
2023
|
+
* surface formerly reached via `serve --ui`.
|
|
2024
|
+
*/
|
|
2025
|
+
program
|
|
2026
|
+
.command('desktop')
|
|
2027
|
+
.description('Start the SpecShip Desktop dashboard + HTTP API (binds 127.0.0.1)')
|
|
2028
|
+
.option('-p, --path <path>', 'Project path (default: cwd, else your most recent initialized project)')
|
|
2029
|
+
.option('--port <n>', 'HTTP port (default 4242)')
|
|
2030
|
+
.option('--host <h>', 'HTTP bind host (default 127.0.0.1)')
|
|
2031
|
+
.option('--ingest', 'Enable the Claude Code JSONL transcript watcher', true)
|
|
2032
|
+
.option('--no-ingest', 'Disable the Claude Code JSONL transcript watcher')
|
|
2033
|
+
.option('--web-dir <path>', 'Path to a built desktop SPA (index.html lives here); auto-detected by default from the bundled ui/dist')
|
|
2034
|
+
.option('--no-web', 'Run headless (API only, no dashboard SPA)')
|
|
2035
|
+
.option('--no-watch', 'Disable the file watcher (no auto-sync; useful on slow filesystems like WSL2 /mnt drives)')
|
|
2036
|
+
.option('--mcp', 'Also start the MCP stdio server against the resolved project')
|
|
2037
|
+
.action(async (options) => {
|
|
2038
|
+
await runDesktop(options);
|
|
2039
|
+
});
|
|
1990
2040
|
/**
|
|
1991
2041
|
* specship unlock [path]
|
|
1992
2042
|
*/
|
|
@@ -2600,6 +2650,24 @@ function main() {
|
|
|
2600
2650
|
.command('cheatsheet')
|
|
2601
2651
|
.description('Print the SpecShip session cheat-sheet (used by the SessionStart hook).')
|
|
2602
2652
|
.action(async () => {
|
|
2653
|
+
// Seed the model marker from the SessionStart payload (REQ-MODCTX-001.A6)
|
|
2654
|
+
// so the very first prompt of a brand-new session already runs at the
|
|
2655
|
+
// right tier — the transcript channel has no assistant turn to read yet.
|
|
2656
|
+
// TTY-guarded: a human running `specship cheatsheet` by hand has no piped
|
|
2657
|
+
// stdin, and waiting on it would hang the command.
|
|
2658
|
+
if (!process.stdin.isTTY) {
|
|
2659
|
+
const chunks = [];
|
|
2660
|
+
try {
|
|
2661
|
+
for await (const c of process.stdin)
|
|
2662
|
+
chunks.push(c);
|
|
2663
|
+
}
|
|
2664
|
+
catch { /* no stdin — nothing to seed */ }
|
|
2665
|
+
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
2666
|
+
if (raw) {
|
|
2667
|
+
const { recordModelFromSessionStart } = await Promise.resolve().then(() => __importStar(require('../mcp/model-context')));
|
|
2668
|
+
recordModelFromSessionStart(raw);
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2603
2671
|
const { buildCheatsheetPayload } = await Promise.resolve().then(() => __importStar(require('../activation/cheatsheet')));
|
|
2604
2672
|
const payload = buildCheatsheetPayload();
|
|
2605
2673
|
if (payload)
|