@bilalimamoglu/sift 0.5.0 → 0.5.1
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/cli.js +215 -42
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,9 @@ function getDefaultCodexGlobalSkillPath(homeDir = os.homedir()) {
|
|
|
24
24
|
function getDefaultCursorGlobalSkillPath(homeDir = os.homedir()) {
|
|
25
25
|
return path.join(homeDir, ".cursor", "skills", "sift", "SKILL.md");
|
|
26
26
|
}
|
|
27
|
+
function getDefaultCopilotInstructionsPath(cwd = process.cwd()) {
|
|
28
|
+
return path.join(cwd, ".github", "copilot-instructions.md");
|
|
29
|
+
}
|
|
27
30
|
function getDefaultClaudeGlobalInstructionsPath(homeDir = os.homedir()) {
|
|
28
31
|
return path.join(homeDir, ".claude", "CLAUDE.md");
|
|
29
32
|
}
|
|
@@ -762,6 +765,7 @@ function describeInsufficientBehavior(mode) {
|
|
|
762
765
|
import { execFileSync } from "child_process";
|
|
763
766
|
import { clearScreenDown, cursorTo, moveCursor } from "readline";
|
|
764
767
|
import { stdin as defaultStdin } from "process";
|
|
768
|
+
import stripAnsi from "strip-ansi";
|
|
765
769
|
var PROMPT_BACK = "__sift_back__";
|
|
766
770
|
var PROMPT_BACK_LABEL = "\u2190 Back";
|
|
767
771
|
function color(text, rgb, args = {}) {
|
|
@@ -849,6 +853,16 @@ function styleOption(option, selected, colorize) {
|
|
|
849
853
|
dim: !selected && Boolean(palette.dimWhenIdle)
|
|
850
854
|
})}${trailing}`;
|
|
851
855
|
}
|
|
856
|
+
function getTerminalColumns(stream) {
|
|
857
|
+
return typeof stream.columns === "number" && stream.columns > 0 ? stream.columns : 80;
|
|
858
|
+
}
|
|
859
|
+
function getVisualLineCount(line, columns) {
|
|
860
|
+
const visibleLength = stripAnsi(line).length;
|
|
861
|
+
return Math.max(1, Math.ceil(visibleLength / columns));
|
|
862
|
+
}
|
|
863
|
+
function getVisualBlockHeight(lines, columns) {
|
|
864
|
+
return lines.reduce((total, line) => total + getVisualLineCount(line, columns), 0);
|
|
865
|
+
}
|
|
852
866
|
function setPosixEcho(enabled) {
|
|
853
867
|
const command = enabled ? "echo" : "-echo";
|
|
854
868
|
try {
|
|
@@ -902,7 +916,7 @@ async function promptSelect(args) {
|
|
|
902
916
|
});
|
|
903
917
|
output.write(`${lines.join("\n")}
|
|
904
918
|
`);
|
|
905
|
-
previousLineCount = lines
|
|
919
|
+
previousLineCount = getVisualBlockHeight(lines, getTerminalColumns(stream));
|
|
906
920
|
};
|
|
907
921
|
const cleanup = (selected) => {
|
|
908
922
|
if (previousLineCount > 0) {
|
|
@@ -9629,11 +9643,11 @@ function buildSafetyStderrNotice(report) {
|
|
|
9629
9643
|
}
|
|
9630
9644
|
|
|
9631
9645
|
// src/core/sanitize.ts
|
|
9632
|
-
import
|
|
9646
|
+
import stripAnsi2 from "strip-ansi";
|
|
9633
9647
|
function sanitizeInput(input, stripAnsiEnabled) {
|
|
9634
9648
|
let output = input;
|
|
9635
9649
|
if (stripAnsiEnabled) {
|
|
9636
|
-
output =
|
|
9650
|
+
output = stripAnsi2(output);
|
|
9637
9651
|
}
|
|
9638
9652
|
return output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\u0000/g, "").replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
9639
9653
|
}
|
|
@@ -12262,6 +12276,7 @@ async function runHook(args, deps = defaultHookDeps) {
|
|
|
12262
12276
|
}
|
|
12263
12277
|
|
|
12264
12278
|
// src/commands/install.ts
|
|
12279
|
+
import fs9 from "fs";
|
|
12265
12280
|
import os5 from "os";
|
|
12266
12281
|
import path10 from "path";
|
|
12267
12282
|
import { emitKeypressEvents as emitKeypressEvents2 } from "readline";
|
|
@@ -12271,10 +12286,42 @@ import {
|
|
|
12271
12286
|
stdin as defaultStdin4,
|
|
12272
12287
|
stdout as defaultStdout3
|
|
12273
12288
|
} from "process";
|
|
12289
|
+
|
|
12290
|
+
// src/runtime-payloads/copilot-instructions.ts
|
|
12291
|
+
var COPILOT_INSTRUCTIONS_MARKER = "<!-- sift:generated copilot-instructions -->";
|
|
12292
|
+
function renderCopilotInstructions() {
|
|
12293
|
+
return [
|
|
12294
|
+
COPILOT_INSTRUCTIONS_MARKER,
|
|
12295
|
+
"",
|
|
12296
|
+
"# Sift",
|
|
12297
|
+
"",
|
|
12298
|
+
"Use `sift` as the first pass when command output is long, noisy, and non-interactive.",
|
|
12299
|
+
"The goal is to turn failure walls into grouped issues, likely root causes, and the next useful step before reading raw logs.",
|
|
12300
|
+
"",
|
|
12301
|
+
"## Repository Guidance",
|
|
12302
|
+
"",
|
|
12303
|
+
"- Start with `sift exec` before reading raw logs when the output is long or noisy.",
|
|
12304
|
+
"- For test failure walls, prefer `sift exec --preset test-status -- <test command>` first.",
|
|
12305
|
+
"- If `standard` already shows the root cause, stop there and read the relevant source instead of chasing more output.",
|
|
12306
|
+
"- After a fix, use `sift rerun` to refresh the same test suite and confirm what changed.",
|
|
12307
|
+
"- Keep edits focused and update tests when behavior changes.",
|
|
12308
|
+
"- Prefer the existing repo conventions in nearby code before introducing new patterns.",
|
|
12309
|
+
"- Keep generated sift-owned files intact; do not hand-edit them unless you are intentionally changing the generator.",
|
|
12310
|
+
"- Run `npm test` and `npm run typecheck` before handing off code changes.",
|
|
12311
|
+
"",
|
|
12312
|
+
"## Notes",
|
|
12313
|
+
"",
|
|
12314
|
+
"- This repository uses `sift` as the CLI runtime and `copilot-instructions.md` as a repo-wide guidance surface for Copilot.",
|
|
12315
|
+
"- The instructions are intentionally short so they stay useful instead of becoming another wall of text."
|
|
12316
|
+
].join("\n");
|
|
12317
|
+
}
|
|
12318
|
+
|
|
12319
|
+
// src/commands/install.ts
|
|
12274
12320
|
var INSTALL_TITLES = {
|
|
12275
12321
|
codex: "Codex",
|
|
12276
12322
|
claude: "Claude",
|
|
12277
|
-
cursor: "Cursor"
|
|
12323
|
+
cursor: "Cursor",
|
|
12324
|
+
copilot: "Copilot"
|
|
12278
12325
|
};
|
|
12279
12326
|
function createInstallTerminalIO() {
|
|
12280
12327
|
let rl;
|
|
@@ -12321,10 +12368,10 @@ function normalizeInstallRuntime(value) {
|
|
|
12321
12368
|
if (value === void 0 || value === null || value === "") {
|
|
12322
12369
|
return void 0;
|
|
12323
12370
|
}
|
|
12324
|
-
if (value === "codex" || value === "claude" || value === "cursor" || value === "all") {
|
|
12371
|
+
if (value === "codex" || value === "claude" || value === "cursor" || value === "copilot" || value === "all") {
|
|
12325
12372
|
return value;
|
|
12326
12373
|
}
|
|
12327
|
-
throw new Error("Invalid runtime. Use codex, claude, cursor, or all.");
|
|
12374
|
+
throw new Error("Invalid runtime. Use codex, claude, cursor, copilot, or all.");
|
|
12328
12375
|
}
|
|
12329
12376
|
function normalizeInstallScope(value) {
|
|
12330
12377
|
if (value === void 0 || value === null || value === "") {
|
|
@@ -12375,15 +12422,43 @@ function getLocalTargetLabel(runtime, cwd = process.cwd()) {
|
|
|
12375
12422
|
if (runtime === "claude") {
|
|
12376
12423
|
return path10.join(cwd, "CLAUDE.md");
|
|
12377
12424
|
}
|
|
12425
|
+
if (runtime === "copilot") {
|
|
12426
|
+
return getDefaultCopilotInstructionsPath(cwd);
|
|
12427
|
+
}
|
|
12378
12428
|
return path10.join(cwd, ".cursor", "skills", "sift", "SKILL.md");
|
|
12379
12429
|
}
|
|
12380
12430
|
function describeScopeChoice(args) {
|
|
12381
12431
|
const targets = getInstallTargets(args.runtime);
|
|
12382
12432
|
const labels = targets.map(
|
|
12383
|
-
(agent) => args.scope === "global" ? getGlobalTargetLabel(agent, args.homeDir) : getLocalTargetLabel(agent, args.cwd)
|
|
12433
|
+
(agent) => args.runtime === "copilot" ? getLocalTargetLabel("copilot", args.cwd) : args.scope === "global" ? getGlobalTargetLabel(agent, args.homeDir) : getLocalTargetLabel(agent, args.cwd)
|
|
12384
12434
|
);
|
|
12385
12435
|
return labels.join(" + ");
|
|
12386
12436
|
}
|
|
12437
|
+
function getCopilotInstructionsTargetPath(cwd) {
|
|
12438
|
+
return getDefaultCopilotInstructionsPath(cwd ?? process.cwd());
|
|
12439
|
+
}
|
|
12440
|
+
function inspectCopilotInstructionsOwnership(content) {
|
|
12441
|
+
if (content === void 0) {
|
|
12442
|
+
return "missing";
|
|
12443
|
+
}
|
|
12444
|
+
return content.includes("<!-- sift:generated copilot-instructions -->") ? "managed" : "custom";
|
|
12445
|
+
}
|
|
12446
|
+
function readOptionalFile2(targetPath) {
|
|
12447
|
+
if (!fs9.existsSync(targetPath)) {
|
|
12448
|
+
return void 0;
|
|
12449
|
+
}
|
|
12450
|
+
const stats = fs9.statSync(targetPath);
|
|
12451
|
+
if (!stats.isFile()) {
|
|
12452
|
+
throw new Error(`${targetPath} exists but is not a file.`);
|
|
12453
|
+
}
|
|
12454
|
+
return fs9.readFileSync(targetPath, "utf8");
|
|
12455
|
+
}
|
|
12456
|
+
function writeTextFileAtomic3(targetPath, content) {
|
|
12457
|
+
fs9.mkdirSync(path10.dirname(targetPath), { recursive: true });
|
|
12458
|
+
const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
|
|
12459
|
+
fs9.writeFileSync(tempPath, content, "utf8");
|
|
12460
|
+
fs9.renameSync(tempPath, targetPath);
|
|
12461
|
+
}
|
|
12387
12462
|
async function promptWithMenu(args) {
|
|
12388
12463
|
const defaultIndex = args.defaultIndex ?? 0;
|
|
12389
12464
|
if (args.io.select) {
|
|
@@ -12449,6 +12524,10 @@ async function promptForRuntime(io) {
|
|
|
12449
12524
|
label: "Cursor (.cursor/skills/sift/SKILL.md / ~/.cursor/skills/sift/SKILL.md) - native skill path for Cursor without inventing a second runtime",
|
|
12450
12525
|
value: "cursor"
|
|
12451
12526
|
},
|
|
12527
|
+
{
|
|
12528
|
+
label: "Copilot (.github/copilot-instructions.md) - repository instructions for GitHub Copilot, repo-only by design",
|
|
12529
|
+
value: "copilot"
|
|
12530
|
+
},
|
|
12452
12531
|
{
|
|
12453
12532
|
label: "All - Codex + Claude together if you refuse to pick favorites today",
|
|
12454
12533
|
value: "all"
|
|
@@ -12522,12 +12601,6 @@ function writeSuccessSummary(args) {
|
|
|
12522
12601
|
const ui = createPresentation(args.io.stdoutIsTTY);
|
|
12523
12602
|
const targets = getInstallTargets(args.runtime);
|
|
12524
12603
|
const scopeLabel = args.scope === "global" ? "global" : "local";
|
|
12525
|
-
const targetLabel = describeScopeChoice({
|
|
12526
|
-
runtime: args.runtime,
|
|
12527
|
-
scope: args.scope,
|
|
12528
|
-
cwd: args.cwd,
|
|
12529
|
-
homeDir: args.homeDir
|
|
12530
|
-
});
|
|
12531
12604
|
if (args.io.stdoutIsTTY) {
|
|
12532
12605
|
args.io.write(`
|
|
12533
12606
|
${ui.success("Installed runtime support.")}
|
|
@@ -12535,6 +12608,33 @@ ${ui.success("Installed runtime support.")}
|
|
|
12535
12608
|
} else {
|
|
12536
12609
|
args.io.write("Installed runtime support.\n");
|
|
12537
12610
|
}
|
|
12611
|
+
if (targets.includes("copilot")) {
|
|
12612
|
+
const targetLabel2 = getCopilotInstructionsTargetPath(args.cwd);
|
|
12613
|
+
args.io.write(`${ui.note("Copilot instructions installed for this repository.")}
|
|
12614
|
+
`);
|
|
12615
|
+
args.io.write(`${ui.note(`Repo-local instructions live at ${targetLabel2}.`)}
|
|
12616
|
+
`);
|
|
12617
|
+
args.io.write(`${ui.note("Copilot is repo-only here; there is no global install target.")}
|
|
12618
|
+
`);
|
|
12619
|
+
args.io.write(`
|
|
12620
|
+
${ui.section("Try next")}
|
|
12621
|
+
`);
|
|
12622
|
+
args.io.write(` ${ui.command("sift exec --preset test-status -- pytest -q")}${ui.note(" # default first pass")}
|
|
12623
|
+
`);
|
|
12624
|
+
args.io.write(` ${ui.command("sift doctor")}${ui.note(" # verify the setup and see what happens on ambiguous cases")}
|
|
12625
|
+
`);
|
|
12626
|
+
args.io.write(`${ui.note(getDefaultExecPathLine())}
|
|
12627
|
+
`);
|
|
12628
|
+
args.io.write(`${ui.note(getHookBetaLine())}
|
|
12629
|
+
`);
|
|
12630
|
+
return;
|
|
12631
|
+
}
|
|
12632
|
+
const targetLabel = describeScopeChoice({
|
|
12633
|
+
runtime: args.runtime,
|
|
12634
|
+
scope: args.scope,
|
|
12635
|
+
cwd: args.cwd,
|
|
12636
|
+
homeDir: args.homeDir
|
|
12637
|
+
});
|
|
12538
12638
|
args.io.write(
|
|
12539
12639
|
`${ui.note(`Runtime instructions installed for ${targets.map((target) => INSTALL_TITLES[target]).join(" + ")} in ${scopeLabel} scope.`)}
|
|
12540
12640
|
`
|
|
@@ -12589,6 +12689,21 @@ ${ui.section("Try next")}
|
|
|
12589
12689
|
function writePreflightSummary(args) {
|
|
12590
12690
|
const ui = createPresentation(args.io.stdoutIsTTY);
|
|
12591
12691
|
const runtimeTargets = getInstallTargets(args.runtime);
|
|
12692
|
+
if (runtimeTargets.includes("copilot")) {
|
|
12693
|
+
const targetPath = getCopilotInstructionsTargetPath(args.cwd);
|
|
12694
|
+
args.io.write(`
|
|
12695
|
+
${ui.section("Install preflight")}
|
|
12696
|
+
`);
|
|
12697
|
+
args.io.write(`${ui.note("Will write repo-local instructions for GitHub Copilot:")}
|
|
12698
|
+
`);
|
|
12699
|
+
args.io.write(` ${ui.command(targetPath)}
|
|
12700
|
+
`);
|
|
12701
|
+
args.io.write(`${ui.note("Will not write shell rc files, PATH entries, git hooks, or arbitrary repo files.")}
|
|
12702
|
+
`);
|
|
12703
|
+
args.io.write(`${ui.note("Managed files update only when sift can prove ownership.")}
|
|
12704
|
+
`);
|
|
12705
|
+
return;
|
|
12706
|
+
}
|
|
12592
12707
|
const writeTargets = runtimeTargets.flatMap((runtime) => {
|
|
12593
12708
|
if (runtime === "codex") {
|
|
12594
12709
|
return [
|
|
@@ -12636,6 +12751,7 @@ ${ui.section("Install preflight")}
|
|
|
12636
12751
|
}
|
|
12637
12752
|
async function installRuntimeSupport(options) {
|
|
12638
12753
|
const io = options.io ?? createInstallTerminalIO();
|
|
12754
|
+
const runtimeIsCopilot = options.runtime === "copilot";
|
|
12639
12755
|
const getPreviousEditableStep = (step) => {
|
|
12640
12756
|
if (step === "runtime") {
|
|
12641
12757
|
return void 0;
|
|
@@ -12667,9 +12783,13 @@ async function installRuntimeSupport(options) {
|
|
|
12667
12783
|
return void 0;
|
|
12668
12784
|
};
|
|
12669
12785
|
try {
|
|
12670
|
-
if (
|
|
12786
|
+
if (runtimeIsCopilot && options.scope === "global") {
|
|
12787
|
+
io.error("sift install copilot is repo-only. Use `sift install copilot --scope local` or omit --scope.\n");
|
|
12788
|
+
return 1;
|
|
12789
|
+
}
|
|
12790
|
+
if ((!io.stdinIsTTY || !io.stdoutIsTTY) && (!options.runtime || !runtimeIsCopilot && !options.scope || !options.yes)) {
|
|
12671
12791
|
io.error(
|
|
12672
|
-
"sift install is interactive and requires a TTY. For non-interactive use `sift install codex --scope global --yes`.\n"
|
|
12792
|
+
"sift install is interactive and requires a TTY. For non-interactive use `sift install codex --scope global --yes` or `sift install copilot --yes`.\n"
|
|
12673
12793
|
);
|
|
12674
12794
|
return 1;
|
|
12675
12795
|
}
|
|
@@ -12681,17 +12801,24 @@ async function installRuntimeSupport(options) {
|
|
|
12681
12801
|
let operationMode = options.operationMode;
|
|
12682
12802
|
let scope = options.scope;
|
|
12683
12803
|
let step;
|
|
12804
|
+
if (runtime === "copilot") {
|
|
12805
|
+
scope = "repo";
|
|
12806
|
+
operationMode ??= "agent-escalation";
|
|
12807
|
+
}
|
|
12684
12808
|
if (!io.stdinIsTTY || !io.stdoutIsTTY) {
|
|
12685
12809
|
runtime ??= options.runtime;
|
|
12686
12810
|
operationMode ??= "agent-escalation";
|
|
12811
|
+
if (runtime === "copilot") {
|
|
12812
|
+
scope = "repo";
|
|
12813
|
+
}
|
|
12687
12814
|
step = void 0;
|
|
12688
12815
|
} else if (!runtime) {
|
|
12689
12816
|
step = "runtime";
|
|
12690
|
-
} else if (!operationMode) {
|
|
12817
|
+
} else if (runtime !== "copilot" && !operationMode) {
|
|
12691
12818
|
step = "mode";
|
|
12692
|
-
} else if (!scope) {
|
|
12819
|
+
} else if (runtime !== "copilot" && !scope) {
|
|
12693
12820
|
step = "scope";
|
|
12694
|
-
} else if (operationMode === "provider-assisted") {
|
|
12821
|
+
} else if (runtime !== "copilot" && operationMode === "provider-assisted") {
|
|
12695
12822
|
step = "provider";
|
|
12696
12823
|
}
|
|
12697
12824
|
while (step) {
|
|
@@ -12704,6 +12831,12 @@ ${createPresentation(io.stdoutIsTTY).note("Install canceled before we touched an
|
|
|
12704
12831
|
return 0;
|
|
12705
12832
|
}
|
|
12706
12833
|
runtime = runtimeChoice;
|
|
12834
|
+
if (runtime === "copilot") {
|
|
12835
|
+
scope = "repo";
|
|
12836
|
+
operationMode ??= "agent-escalation";
|
|
12837
|
+
step = void 0;
|
|
12838
|
+
continue;
|
|
12839
|
+
}
|
|
12707
12840
|
step = !operationMode ? "mode" : !scope ? "scope" : operationMode === "provider-assisted" ? "provider" : void 0;
|
|
12708
12841
|
continue;
|
|
12709
12842
|
}
|
|
@@ -12754,41 +12887,81 @@ ${createPresentation(io.stdoutIsTTY).note("Install canceled before we touched an
|
|
|
12754
12887
|
step = operationMode === "provider-assisted" ? "provider" : void 0;
|
|
12755
12888
|
continue;
|
|
12756
12889
|
}
|
|
12757
|
-
if (
|
|
12758
|
-
|
|
12759
|
-
|
|
12890
|
+
if (step === "provider") {
|
|
12891
|
+
if (scope === "repo") {
|
|
12892
|
+
io.write(
|
|
12893
|
+
`
|
|
12760
12894
|
${createPresentation(io.stdoutIsTTY).note("Local only applies to the runtime instructions in this repo. Provider fallback config is still machine-wide so sift can reuse it anywhere.")}
|
|
12761
12895
|
`
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12896
|
+
);
|
|
12897
|
+
}
|
|
12898
|
+
io.write(`
|
|
12765
12899
|
${createPresentation(io.stdoutIsTTY).info("Next: provider setup. Press Esc at any step to go back.")}
|
|
12766
12900
|
`);
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12901
|
+
const setupStatus = await configSetup({
|
|
12902
|
+
io,
|
|
12903
|
+
env: process.env,
|
|
12904
|
+
embedded: true,
|
|
12905
|
+
forcedMode: "provider-assisted",
|
|
12906
|
+
targetPath: getDefaultGlobalConfigPath(options.homeDir)
|
|
12907
|
+
});
|
|
12908
|
+
if (setupStatus === CONFIG_SETUP_BACK) {
|
|
12909
|
+
const previous = getPreviousEditableStep("provider");
|
|
12910
|
+
if (!previous) {
|
|
12911
|
+
io.write(`
|
|
12778
12912
|
${createPresentation(io.stdoutIsTTY).note("Install canceled before we touched anything.")}
|
|
12779
12913
|
`);
|
|
12780
|
-
|
|
12914
|
+
return 0;
|
|
12915
|
+
}
|
|
12916
|
+
step = previous;
|
|
12917
|
+
continue;
|
|
12918
|
+
}
|
|
12919
|
+
if (setupStatus !== 0) {
|
|
12920
|
+
return setupStatus;
|
|
12781
12921
|
}
|
|
12782
|
-
step =
|
|
12922
|
+
step = void 0;
|
|
12783
12923
|
continue;
|
|
12784
12924
|
}
|
|
12785
|
-
if (setupStatus !== 0) {
|
|
12786
|
-
return setupStatus;
|
|
12787
|
-
}
|
|
12788
|
-
step = void 0;
|
|
12789
12925
|
}
|
|
12790
12926
|
const nestedIo = createNestedInstallIO(io);
|
|
12927
|
+
if (runtime === "copilot") {
|
|
12928
|
+
const targetPath = getCopilotInstructionsTargetPath(options.cwd);
|
|
12929
|
+
const existingContent = readOptionalFile2(targetPath);
|
|
12930
|
+
const ownership = inspectCopilotInstructionsOwnership(existingContent);
|
|
12931
|
+
if (ownership === "custom") {
|
|
12932
|
+
io.error(
|
|
12933
|
+
`Refusing to overwrite a custom copilot-instructions.md at ${targetPath}. Move it, remove it manually, or choose a different target path.
|
|
12934
|
+
`
|
|
12935
|
+
);
|
|
12936
|
+
return 1;
|
|
12937
|
+
}
|
|
12938
|
+
if (io.stdoutIsTTY) {
|
|
12939
|
+
writePreflightSummary({
|
|
12940
|
+
io,
|
|
12941
|
+
runtime,
|
|
12942
|
+
scope: "repo",
|
|
12943
|
+
operationMode: operationMode ?? "agent-escalation",
|
|
12944
|
+
cwd: options.cwd,
|
|
12945
|
+
homeDir: options.homeDir
|
|
12946
|
+
});
|
|
12947
|
+
}
|
|
12948
|
+
writeTextFileAtomic3(targetPath, `${renderCopilotInstructions()}
|
|
12949
|
+
`);
|
|
12950
|
+
writeSuccessSummary({
|
|
12951
|
+
io,
|
|
12952
|
+
version: options.version,
|
|
12953
|
+
runtime,
|
|
12954
|
+
scope: "repo",
|
|
12955
|
+
operationMode: operationMode ?? "agent-escalation",
|
|
12956
|
+
cwd: options.cwd,
|
|
12957
|
+
homeDir: options.homeDir
|
|
12958
|
+
});
|
|
12959
|
+
return 0;
|
|
12960
|
+
}
|
|
12791
12961
|
for (const runtimeTarget of getInstallTargets(runtime)) {
|
|
12962
|
+
if (runtimeTarget === "copilot") {
|
|
12963
|
+
continue;
|
|
12964
|
+
}
|
|
12792
12965
|
const status = runtimeTarget === "cursor" ? await installSkill({
|
|
12793
12966
|
runtime: "cursor",
|
|
12794
12967
|
scope,
|
|
@@ -13881,7 +14054,7 @@ function createCliApp(args = {}) {
|
|
|
13881
14054
|
stdout.write(`${output}
|
|
13882
14055
|
`);
|
|
13883
14056
|
});
|
|
13884
|
-
cli.command("install [runtime]", "Interactive runtime installer for Codex, Claude, and
|
|
14057
|
+
cli.command("install [runtime]", "Interactive runtime installer for Codex, Claude, Cursor, and Copilot repo instructions").usage("install [runtime] [options]").example("install").example("install codex").example("install cursor").example("install copilot").example("install codex --scope global --yes").example("install all --scope local --yes").option("--scope <scope>", "Install scope: local | global").option("--yes", "Skip prompts when runtime and scope are already provided").action(async (runtime, options) => {
|
|
13885
14058
|
process.exitCode = await deps.installRuntimeSupport({
|
|
13886
14059
|
runtime: normalizeInstallRuntime(runtime),
|
|
13887
14060
|
scope: normalizeInstallScope(options.scope),
|