acstack 0.48.2 → 0.48.5
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/plugin.json +2 -2
- package/README.md +6 -5
- package/TROUBLESHOOTING.md +17 -17
- package/assets/terminal-workspace/config.example.yaml +4 -1
- package/assets/terminal-workspace/setup.sh +12 -0
- package/cli/README.md +1 -1
- package/cli/dist/index.js +1 -1
- package/cli/dist/index.js.map +1 -1
- package/cli/package.json +3 -3
- package/docs/terminal-workspace.md +1 -0
- package/package.json +2 -2
- package/pi/extension.ts +86 -40
package/cli/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "acstack-cli",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.5",
|
|
4
4
|
"description": "CLI for the ACStack agentic coding stack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "git+https://github.com/ac8318740/
|
|
12
|
+
"url": "git+https://github.com/ac8318740/acstack.git",
|
|
13
13
|
"directory": "cli"
|
|
14
14
|
},
|
|
15
15
|
"bin": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"yaml": "^2.7.0",
|
|
56
56
|
"zod": "^3.24.0"
|
|
57
57
|
},
|
|
58
|
-
"homepage": "https://github.com/ac8318740/
|
|
58
|
+
"homepage": "https://github.com/ac8318740/acstack/tree/main/cli",
|
|
59
59
|
"keywords": [
|
|
60
60
|
"agentic-coding",
|
|
61
61
|
"acstack",
|
|
@@ -359,6 +359,7 @@ What `apply` does:
|
|
|
359
359
|
- Setup leaves Claude Code and Codex alone, and removes bili from them if an older setup added it
|
|
360
360
|
- Set `pi.billion_context: false` to leave it out, or to remove it later if this setup installed it
|
|
361
361
|
- It installs `@juicesharp/rpiv-todo` and `pi-plugin-manager` by default
|
|
362
|
+
- When todo is on, `apply` suggests a todo-discipline line for the user's global Pi context file if it is missing
|
|
362
363
|
- Set `pi.todo: false` or `pi.plugin_manager: false` to leave either package out
|
|
363
364
|
- It installs `@juicesharp/rpiv-ask-user-question` as pi's question tool by default
|
|
364
365
|
- ACStack uses it because decisions can include markdown, code and artifact previews
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "acstack",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Agentic coding stack with first-class Claude Code and pi support: skills, orchestrator instructions, and verification agents.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/ac8318740/
|
|
9
|
+
"url": "git+https://github.com/ac8318740/acstack.git"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
12
12
|
"pi-package",
|
package/pi/extension.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* before_agent_start list ACStack's skills in the system prompt in every
|
|
11
11
|
* session, and add orchestrator/AGENTS.md in a
|
|
12
12
|
* acstack project (hooks/session-start.sh)
|
|
13
|
-
* add the writing style and its per-turn reminder
|
|
14
|
-
* the
|
|
13
|
+
* add the writing style and its per-turn reminder
|
|
14
|
+
* from the SSOT style file (hooks/ac-writing-style-reminder.sh)
|
|
15
15
|
* agent_before_settle nudge with a continuity-versus-freshness checkpoint
|
|
16
16
|
* as context fills (hooks/context-pressure.sh)
|
|
17
17
|
* session_compact re-inject acstack/HANDOFF.md after a compaction, and
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
* hooks/context-pressure.sh)
|
|
20
20
|
*
|
|
21
21
|
* It also registers /acstack <skill>, a /acstack:<skill> command per skill,
|
|
22
|
-
* and /acstack-writing-style
|
|
23
|
-
*
|
|
24
|
-
* /skill:<name> commands for them.
|
|
22
|
+
* and /acstack-writing-style for the bundled/default/custom style choice.
|
|
23
|
+
* The first two forms are the only way a user runs an ACStack skill on pi:
|
|
24
|
+
* package.json lists no skills, so pi adds no /skill:<name> commands for them.
|
|
25
25
|
*
|
|
26
26
|
* Only type imports come from pi, so Node can strip the types and load this
|
|
27
27
|
* file in tests/test-pi-extension.sh with a stub API.
|
|
@@ -45,6 +45,12 @@ function agentDir(): string {
|
|
|
45
45
|
return process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".pi", "agent");
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
const settingsFile = (): string => path.join(agentDir(), "acstack.json");
|
|
49
|
+
|
|
50
|
+
type WritingStyleMode = "default" | "off" | "custom";
|
|
51
|
+
type WritingStyleSettings = { mode?: WritingStyleMode; path?: string };
|
|
52
|
+
type AcstackSettings = { writingStyle?: boolean | WritingStyleSettings };
|
|
53
|
+
|
|
48
54
|
function readText(file: string): string | undefined {
|
|
49
55
|
try {
|
|
50
56
|
return fs.readFileSync(file, "utf-8");
|
|
@@ -53,6 +59,34 @@ function readText(file: string): string | undefined {
|
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
function readSettings(): AcstackSettings {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(readText(settingsFile()) ?? "{}");
|
|
65
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
66
|
+
} catch {
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function writeSettings(settings: AcstackSettings): void {
|
|
72
|
+
fs.mkdirSync(path.dirname(settingsFile()), { recursive: true });
|
|
73
|
+
fs.writeFileSync(settingsFile(), `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function writingStyleSettings(settings: AcstackSettings = readSettings()): WritingStyleSettings {
|
|
77
|
+
const value = settings.writingStyle;
|
|
78
|
+
if (value === false) return { mode: "off" };
|
|
79
|
+
if (value === true || value === undefined) return { mode: "default" };
|
|
80
|
+
if (value && typeof value === "object") return { mode: value.mode ?? "default", path: value.path };
|
|
81
|
+
return { mode: "default" };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function expandUserPath(file: string, cwd = process.cwd()): string {
|
|
85
|
+
if (file === "~") return os.homedir();
|
|
86
|
+
if (file.startsWith(`~${path.sep}`)) return path.join(os.homedir(), file.slice(2));
|
|
87
|
+
return path.isAbsolute(file) ? file : path.resolve(cwd, file);
|
|
88
|
+
}
|
|
89
|
+
|
|
56
90
|
function report(ctx: ExtensionContext, message: string, level: "info" | "warning" | "error" = "info"): void {
|
|
57
91
|
if (ctx.hasUI) ctx.ui.notify(message, level);
|
|
58
92
|
else process.stderr.write(`${message}\n`);
|
|
@@ -172,22 +206,6 @@ function linkClis(ctx: ExtensionContext): void {
|
|
|
172
206
|
// Writing style
|
|
173
207
|
// --------------------------------------------------------------------------
|
|
174
208
|
|
|
175
|
-
const settingsFile = (): string => path.join(agentDir(), "acstack.json");
|
|
176
|
-
|
|
177
|
-
function readSettings(): { writingStyle?: boolean } {
|
|
178
|
-
try {
|
|
179
|
-
const parsed = JSON.parse(readText(settingsFile()) ?? "{}");
|
|
180
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
181
|
-
} catch {
|
|
182
|
-
return {};
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function writeSettings(settings: { writingStyle?: boolean }): void {
|
|
187
|
-
fs.mkdirSync(path.dirname(settingsFile()), { recursive: true });
|
|
188
|
-
fs.writeFileSync(settingsFile(), `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
189
|
-
}
|
|
190
|
-
|
|
191
209
|
function stripFrontmatter(text: string): string {
|
|
192
210
|
const match = /^---\n[\s\S]*?\n---\n/.exec(text);
|
|
193
211
|
return (match ? text.slice(match[0].length) : text).trim();
|
|
@@ -616,10 +634,16 @@ export default function acstack(pi: ExtensionAPI): void {
|
|
|
616
634
|
else report(ctx, `acstack: could not read ${orchestratorFile}`, "warning");
|
|
617
635
|
}
|
|
618
636
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
637
|
+
const styleCfg = writingStyleSettings();
|
|
638
|
+
if (styleCfg.mode === "off") return;
|
|
639
|
+
const resolvedStyleFile = styleCfg.mode === "custom" && styleCfg.path ? expandUserPath(styleCfg.path) : styleFile;
|
|
640
|
+
const style = readText(resolvedStyleFile);
|
|
641
|
+
if (!style) {
|
|
642
|
+
report(ctx, `acstack: could not read writing style at ${resolvedStyleFile}`, "warning");
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
622
645
|
sections["acstack-writing-style"] = stripFrontmatter(style);
|
|
646
|
+
if (event.messageType !== "user") return;
|
|
623
647
|
const reminder = extractWritingReminder(style);
|
|
624
648
|
if (!reminder) return;
|
|
625
649
|
return { message: { customType: "acstack-writing-style-reminder", content: reminder, display: false } };
|
|
@@ -686,6 +710,44 @@ export default function acstack(pi: ExtensionAPI): void {
|
|
|
686
710
|
else pi.sendUserMessage(message, { deliverAs: "followUp" });
|
|
687
711
|
};
|
|
688
712
|
|
|
713
|
+
pi.registerCommand("acstack-writing-style", {
|
|
714
|
+
description: "Configure ACStack writing style injection: default | off | custom <path>",
|
|
715
|
+
handler: async (args, ctx) => {
|
|
716
|
+
const [choice = "", ...rest] = args.trim().split(/\s+/).filter(Boolean);
|
|
717
|
+
const settings = readSettings();
|
|
718
|
+
const current = writingStyleSettings(settings);
|
|
719
|
+
if (!choice || choice === "show") {
|
|
720
|
+
report(ctx, `acstack: writing style is ${current.mode}${current.path ? ` (${current.path})` : ""} (${settingsFile()}).`);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (choice === "default") {
|
|
724
|
+
settings.writingStyle = { mode: "default" };
|
|
725
|
+
writeSettings(settings);
|
|
726
|
+
report(ctx, `acstack: writing style is default (${settingsFile()}).`);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
if (choice === "off") {
|
|
730
|
+
settings.writingStyle = { mode: "off" };
|
|
731
|
+
writeSettings(settings);
|
|
732
|
+
report(ctx, `acstack: writing style is off (${settingsFile()}).`);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (choice === "custom") {
|
|
736
|
+
const customPath = rest.join(" ").trim();
|
|
737
|
+
if (!customPath) {
|
|
738
|
+
report(ctx, "acstack: usage is /acstack-writing-style custom <path>", "warning");
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
const resolvedPath = expandUserPath(customPath, ctx.cwd);
|
|
742
|
+
settings.writingStyle = { mode: "custom", path: resolvedPath };
|
|
743
|
+
writeSettings(settings);
|
|
744
|
+
report(ctx, `acstack: writing style is custom (${resolvedPath}) (${settingsFile()}).`);
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
report(ctx, "acstack: usage is /acstack-writing-style [show|default|off|custom <path>]", "warning");
|
|
748
|
+
},
|
|
749
|
+
});
|
|
750
|
+
|
|
689
751
|
pi.registerCommand("acstack", {
|
|
690
752
|
description: "Run an ACStack skill: /acstack <skill> [args], e.g. /acstack map",
|
|
691
753
|
handler: async (args, ctx) => {
|
|
@@ -704,20 +766,4 @@ export default function acstack(pi: ExtensionAPI): void {
|
|
|
704
766
|
handler: async (args, ctx) => runSkill(name, args, ctx),
|
|
705
767
|
});
|
|
706
768
|
}
|
|
707
|
-
|
|
708
|
-
pi.registerCommand("acstack-writing-style", {
|
|
709
|
-
description: "Turn the ACStack writing style on or off for every pi session (on | off)",
|
|
710
|
-
handler: async (args, ctx) => {
|
|
711
|
-
const choice = args.trim().toLowerCase();
|
|
712
|
-
const settings = readSettings();
|
|
713
|
-
if (choice === "on" || choice === "off") {
|
|
714
|
-
settings.writingStyle = choice === "on";
|
|
715
|
-
writeSettings(settings);
|
|
716
|
-
} else if (choice) {
|
|
717
|
-
report(ctx, "acstack: usage is /acstack-writing-style on|off", "warning");
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
report(ctx, `acstack: writing style is ${settings.writingStyle ? "on" : "off"} (${settingsFile()}).`);
|
|
721
|
-
},
|
|
722
|
-
});
|
|
723
769
|
}
|