stackai 0.1.1 → 0.1.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/dist/cli.js +173 -35
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -462,6 +462,9 @@ async function writeConfig(config) {
|
|
|
462
462
|
await fs2.mkdir(CONFIG_DIR, { recursive: true });
|
|
463
463
|
await fs2.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2), "utf8");
|
|
464
464
|
}
|
|
465
|
+
async function clearConfig() {
|
|
466
|
+
await fs2.rm(CONFIG_PATH, { force: true });
|
|
467
|
+
}
|
|
465
468
|
|
|
466
469
|
// src/api.ts
|
|
467
470
|
var ApiClient = class {
|
|
@@ -594,7 +597,12 @@ import { Box as Box3, Text as Text3, useApp as useApp2 } from "ink";
|
|
|
594
597
|
import Spinner2 from "ink-spinner";
|
|
595
598
|
import TextInput from "ink-text-input";
|
|
596
599
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
597
|
-
|
|
600
|
+
var ACCENT = "#e8ff47";
|
|
601
|
+
var LOGO = [
|
|
602
|
+
"\u2588\u2580\u2580 \u2580\u2588\u2580 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2584\u2580 \u2588\u2580\u2588 \u2588",
|
|
603
|
+
"\u2584\u2584\u2588 \u2588 \u2588\u2580\u2588 \u2588\u2584\u2584 \u2588\u2580\u2584 \u2588\u2580\u2588 \u2588"
|
|
604
|
+
];
|
|
605
|
+
function Interactive({ session, cwd, version }) {
|
|
598
606
|
const { exit } = useApp2();
|
|
599
607
|
const [history, setHistory] = useState2([]);
|
|
600
608
|
const [input, setInput] = useState2("");
|
|
@@ -619,11 +627,10 @@ function Interactive({ session, cwd }) {
|
|
|
619
627
|
setHistory((prev) => {
|
|
620
628
|
const last = prev[prev.length - 1];
|
|
621
629
|
if (!last || last.kind !== "agent") return prev;
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
entries: applyStep(last.entries, step)
|
|
625
|
-
|
|
626
|
-
return [...prev.slice(0, -1), updated];
|
|
630
|
+
return [
|
|
631
|
+
...prev.slice(0, -1),
|
|
632
|
+
{ kind: "agent", entries: applyStep(last.entries, step) }
|
|
633
|
+
];
|
|
627
634
|
});
|
|
628
635
|
};
|
|
629
636
|
try {
|
|
@@ -635,19 +642,37 @@ function Interactive({ session, cwd }) {
|
|
|
635
642
|
}
|
|
636
643
|
}
|
|
637
644
|
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingY: 1, children: [
|
|
638
|
-
/* @__PURE__ */ jsxs3(
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
645
|
+
/* @__PURE__ */ jsxs3(
|
|
646
|
+
Box3,
|
|
647
|
+
{
|
|
648
|
+
flexDirection: "column",
|
|
649
|
+
borderStyle: "round",
|
|
650
|
+
borderColor: ACCENT,
|
|
651
|
+
paddingX: 2,
|
|
652
|
+
paddingY: 1,
|
|
653
|
+
children: [
|
|
654
|
+
LOGO.map((line, i) => /* @__PURE__ */ jsx3(Text3, { color: ACCENT, bold: true, children: line }, i)),
|
|
655
|
+
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
|
|
656
|
+
"v",
|
|
657
|
+
version,
|
|
658
|
+
" \xB7 MiMo v2.5 Pro \xB7 1M context"
|
|
659
|
+
] }) }),
|
|
660
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: cwd })
|
|
661
|
+
]
|
|
662
|
+
}
|
|
663
|
+
),
|
|
664
|
+
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
|
|
665
|
+
"Describe what you want to build \xB7 type",
|
|
666
|
+
" ",
|
|
667
|
+
/* @__PURE__ */ jsx3(Text3, { color: ACCENT, children: "/exit" }),
|
|
668
|
+
" to quit"
|
|
669
|
+
] }) }),
|
|
648
670
|
history.map(
|
|
649
671
|
(block, i) => block.kind === "user" ? /* @__PURE__ */ jsxs3(Box3, { marginTop: 1, children: [
|
|
650
|
-
/* @__PURE__ */
|
|
672
|
+
/* @__PURE__ */ jsxs3(Text3, { color: ACCENT, bold: true, children: [
|
|
673
|
+
"\u203A",
|
|
674
|
+
" "
|
|
675
|
+
] }),
|
|
651
676
|
/* @__PURE__ */ jsx3(Text3, { children: block.text })
|
|
652
677
|
] }, i) : /* @__PURE__ */ jsx3(EntryLines, { entries: block.entries }, i)
|
|
653
678
|
),
|
|
@@ -655,38 +680,118 @@ function Interactive({ session, cwd }) {
|
|
|
655
680
|
"Error: ",
|
|
656
681
|
error
|
|
657
682
|
] }) }),
|
|
658
|
-
/* @__PURE__ */ jsx3(
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
683
|
+
/* @__PURE__ */ jsx3(
|
|
684
|
+
Box3,
|
|
685
|
+
{
|
|
686
|
+
marginTop: 1,
|
|
687
|
+
borderStyle: "round",
|
|
688
|
+
borderColor: busy ? "gray" : ACCENT,
|
|
689
|
+
paddingX: 1,
|
|
690
|
+
children: busy ? /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
|
|
691
|
+
/* @__PURE__ */ jsx3(Spinner2, { type: "dots" }),
|
|
692
|
+
" working\u2026"
|
|
693
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
694
|
+
/* @__PURE__ */ jsx3(Text3, { color: ACCENT, children: "\u203A " }),
|
|
695
|
+
/* @__PURE__ */ jsx3(
|
|
696
|
+
TextInput,
|
|
697
|
+
{
|
|
698
|
+
value: input,
|
|
699
|
+
onChange: setInput,
|
|
700
|
+
onSubmit,
|
|
701
|
+
placeholder: "message StackAI\u2026"
|
|
702
|
+
}
|
|
703
|
+
)
|
|
704
|
+
] })
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
] });
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// src/ui/login-view.tsx
|
|
711
|
+
import { useState as useState3 } from "react";
|
|
712
|
+
import { Box as Box4, Text as Text4, useApp as useApp3 } from "ink";
|
|
713
|
+
import TextInput2 from "ink-text-input";
|
|
714
|
+
import Spinner3 from "ink-spinner";
|
|
715
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
716
|
+
function LoginView() {
|
|
717
|
+
const { exit } = useApp3();
|
|
718
|
+
const [value, setValue] = useState3("");
|
|
719
|
+
const [phase, setPhase] = useState3("input");
|
|
720
|
+
const [message, setMessage] = useState3("");
|
|
721
|
+
async function submit(raw) {
|
|
722
|
+
const key = raw.trim();
|
|
723
|
+
if (!key) return;
|
|
724
|
+
setPhase("checking");
|
|
725
|
+
try {
|
|
726
|
+
await writeConfig({ apiKey: key, apiUrl: DEFAULT_API_URL });
|
|
727
|
+
const verify = await new ApiClient({
|
|
728
|
+
apiKey: key,
|
|
729
|
+
apiUrl: DEFAULT_API_URL
|
|
730
|
+
}).verify();
|
|
731
|
+
setMessage(`Logged in as @${verify.user.username} \xB7 ${verify.user.tier} tier`);
|
|
732
|
+
setPhase("done");
|
|
733
|
+
} catch (err) {
|
|
734
|
+
setMessage(err instanceof Error ? err.message : String(err));
|
|
735
|
+
setPhase("error");
|
|
736
|
+
} finally {
|
|
737
|
+
setTimeout(() => exit(), 60);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingY: 1, children: [
|
|
741
|
+
/* @__PURE__ */ jsxs4(Box4, { children: [
|
|
742
|
+
/* @__PURE__ */ jsxs4(Text4, { color: "#e8ff47", bold: true, children: [
|
|
743
|
+
"StackAI",
|
|
744
|
+
" "
|
|
745
|
+
] }),
|
|
746
|
+
/* @__PURE__ */ jsx4(Text4, { color: "gray", children: "login" })
|
|
747
|
+
] }),
|
|
748
|
+
phase === "input" && /* @__PURE__ */ jsxs4(Box4, { marginTop: 1, children: [
|
|
749
|
+
/* @__PURE__ */ jsx4(Text4, { children: "API key " }),
|
|
750
|
+
/* @__PURE__ */ jsx4(Text4, { color: "#e8ff47", children: "\u203A " }),
|
|
751
|
+
/* @__PURE__ */ jsx4(
|
|
752
|
+
TextInput2,
|
|
665
753
|
{
|
|
666
|
-
value
|
|
667
|
-
onChange:
|
|
668
|
-
onSubmit,
|
|
669
|
-
|
|
754
|
+
value,
|
|
755
|
+
onChange: setValue,
|
|
756
|
+
onSubmit: submit,
|
|
757
|
+
mask: "*",
|
|
758
|
+
placeholder: "sk_live_..."
|
|
670
759
|
}
|
|
671
760
|
)
|
|
761
|
+
] }),
|
|
762
|
+
phase === "checking" && /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: "gray", children: [
|
|
763
|
+
/* @__PURE__ */ jsx4(Spinner3, { type: "dots" }),
|
|
764
|
+
" verifying\u2026"
|
|
765
|
+
] }) }),
|
|
766
|
+
phase === "done" && /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: "green", children: [
|
|
767
|
+
"\u2713 ",
|
|
768
|
+
message
|
|
769
|
+
] }) }),
|
|
770
|
+
phase === "error" && /* @__PURE__ */ jsx4(Box4, { marginTop: 1, children: /* @__PURE__ */ jsxs4(Text4, { color: "red", children: [
|
|
771
|
+
"\u2717 ",
|
|
772
|
+
message
|
|
672
773
|
] }) })
|
|
673
774
|
] });
|
|
674
775
|
}
|
|
675
776
|
|
|
676
777
|
// src/cli.tsx
|
|
677
|
-
import { jsx as
|
|
678
|
-
var VERSION = "0.1.
|
|
778
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
779
|
+
var VERSION = "0.1.2";
|
|
679
780
|
var HELP = `
|
|
680
781
|
StackAI \u2014 AI coding agent in your terminal
|
|
681
782
|
|
|
682
783
|
Usage
|
|
683
784
|
$ stackai Start an interactive chat session
|
|
684
785
|
$ stackai <prompt> Run the agent once, then exit
|
|
685
|
-
$ stackai
|
|
686
|
-
$ stackai
|
|
786
|
+
$ stackai login Log in (prompts for your API key)
|
|
787
|
+
$ stackai login <api_key> Log in directly
|
|
687
788
|
$ stackai whoami Show current user + usage
|
|
789
|
+
$ stackai logout Remove your saved API key
|
|
688
790
|
$ stackai --help
|
|
689
791
|
$ stackai --version
|
|
792
|
+
|
|
793
|
+
Advanced
|
|
794
|
+
$ stackai auth <key> [url] Save key with a custom API URL
|
|
690
795
|
`;
|
|
691
796
|
async function main() {
|
|
692
797
|
const args = process.argv.slice(2);
|
|
@@ -699,6 +804,37 @@ async function main() {
|
|
|
699
804
|
console.log(VERSION);
|
|
700
805
|
return;
|
|
701
806
|
}
|
|
807
|
+
if (first === "login") {
|
|
808
|
+
const key = args[1];
|
|
809
|
+
if (key) {
|
|
810
|
+
await writeConfig({ apiKey: key, apiUrl: DEFAULT_API_URL });
|
|
811
|
+
try {
|
|
812
|
+
const verify = await new ApiClient({
|
|
813
|
+
apiKey: key,
|
|
814
|
+
apiUrl: DEFAULT_API_URL
|
|
815
|
+
}).verify();
|
|
816
|
+
console.log(
|
|
817
|
+
`\u2713 Logged in as @${verify.user.username} \xB7 ${verify.user.tier} tier`
|
|
818
|
+
);
|
|
819
|
+
} catch (err) {
|
|
820
|
+
console.error(`\u2717 ${err instanceof Error ? err.message : String(err)}`);
|
|
821
|
+
process.exitCode = 1;
|
|
822
|
+
}
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
if (!process.stdin.isTTY) {
|
|
826
|
+
console.error("Run: stackai login <api_key>");
|
|
827
|
+
process.exitCode = 1;
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
render(/* @__PURE__ */ jsx5(LoginView, {}));
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
if (first === "logout") {
|
|
834
|
+
await clearConfig();
|
|
835
|
+
console.log("\u2713 Logged out");
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
702
838
|
if (first === "auth") {
|
|
703
839
|
const key = args[1];
|
|
704
840
|
if (!key) {
|
|
@@ -713,7 +849,7 @@ async function main() {
|
|
|
713
849
|
}
|
|
714
850
|
const config = await readConfig();
|
|
715
851
|
if (!config) {
|
|
716
|
-
console.error("Not
|
|
852
|
+
console.error("Not logged in. Run: stackai login");
|
|
717
853
|
process.exitCode = 1;
|
|
718
854
|
return;
|
|
719
855
|
}
|
|
@@ -744,11 +880,13 @@ async function main() {
|
|
|
744
880
|
process.exitCode = 1;
|
|
745
881
|
return;
|
|
746
882
|
}
|
|
747
|
-
render(
|
|
883
|
+
render(
|
|
884
|
+
/* @__PURE__ */ jsx5(Interactive, { session: runner.session(cwd), cwd, version: VERSION })
|
|
885
|
+
);
|
|
748
886
|
return;
|
|
749
887
|
}
|
|
750
888
|
const prompt = args.join(" ");
|
|
751
|
-
render(/* @__PURE__ */
|
|
889
|
+
render(/* @__PURE__ */ jsx5(RunView, { runner, prompt, cwd }));
|
|
752
890
|
}
|
|
753
891
|
main().catch((err) => {
|
|
754
892
|
console.error(err instanceof Error ? err.message : String(err));
|