supipowers 2.0.1 → 2.1.0
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/README.md +10 -6
- package/package.json +4 -2
- package/skills/harness/SKILL.md +1 -0
- package/src/bootstrap.ts +5 -133
- package/src/commands/clear.ts +6 -6
- package/src/commands/release.ts +3 -1
- package/src/commands/update.ts +1 -1
- package/src/config/defaults.ts +5 -5
- package/src/config/loader.ts +1 -0
- package/src/config/schema.ts +2 -6
- package/src/context/analyzer.ts +104 -35
- package/src/context-mode/knowledge/store.ts +381 -43
- package/src/context-mode/tools.ts +41 -3
- package/src/deps/registry.ts +1 -12
- package/src/fix-pr/assessment.ts +1 -0
- package/src/fix-pr/prompt-builder.ts +1 -0
- package/src/git/commit.ts +76 -18
- package/src/harness/command.ts +103 -6
- package/src/harness/default-agents/docs.md +39 -0
- package/src/harness/docs/config.ts +29 -0
- package/src/harness/docs/glob-match.ts +27 -0
- package/src/harness/docs/index-renderer.ts +82 -0
- package/src/harness/docs/provenance.ts +125 -0
- package/src/harness/docs/regen-decision.ts +167 -0
- package/src/harness/docs/representative-files.ts +175 -0
- package/src/harness/docs/source-hash.ts +106 -0
- package/src/harness/docs/validator.ts +233 -0
- package/src/harness/hooks/layer-context-inject.ts +35 -1
- package/src/harness/hooks/register.ts +24 -3
- package/src/harness/pipeline.ts +20 -5
- package/src/harness/pr-comment/baseline.ts +105 -0
- package/src/harness/pr-comment/ci-env.ts +120 -0
- package/src/harness/pr-comment/gh-poster.ts +227 -0
- package/src/harness/pr-comment/handler.ts +198 -0
- package/src/harness/pr-comment/render.ts +297 -0
- package/src/harness/pr-comment/status.ts +95 -0
- package/src/harness/pr-comment/types.ts +73 -0
- package/src/harness/pr-comment/workflow-summary.ts +47 -0
- package/src/harness/project-paths.ts +95 -0
- package/src/harness/stages/design.ts +1 -0
- package/src/harness/stages/discover.ts +1 -13
- package/src/harness/stages/docs.ts +708 -0
- package/src/harness/stages/implement-apply.ts +877 -0
- package/src/harness/stages/implement.ts +64 -51
- package/src/harness/stages/plan.ts +25 -16
- package/src/harness/stages/validate.ts +370 -0
- package/src/harness/storage.ts +142 -0
- package/src/harness/tools.ts +130 -0
- package/src/mempalace/bridge.ts +207 -41
- package/src/mempalace/config.ts +10 -4
- package/src/mempalace/format.ts +122 -6
- package/src/mempalace/hooks.ts +204 -56
- package/src/mempalace/installer-helper.ts +18 -4
- package/src/mempalace/python/mempalace_bridge.py +128 -3
- package/src/mempalace/runtime.ts +55 -18
- package/src/mempalace/schema.ts +151 -30
- package/src/mempalace/session-summary.ts +5 -0
- package/src/mempalace/tool.ts +17 -4
- package/src/mempalace/upstream-limits.ts +69 -0
- package/src/planning/approval-flow.ts +25 -2
- package/src/planning/planning-ask-tool.ts +34 -4
- package/src/planning/system-prompt.ts +1 -1
- package/src/tool-catalog/active-tool-controller.ts +0 -22
- package/src/tool-catalog/active-tool-planner.ts +0 -26
- package/src/tool-catalog/tool-groups.ts +1 -9
- package/src/types.ts +87 -8
- package/src/ui-design/session.ts +114 -10
- package/src/utils/executable.ts +10 -1
- package/src/workspace/state-paths.ts +1 -1
- package/src/commands/mcp.ts +0 -814
- package/src/mcp/activation.ts +0 -77
- package/src/mcp/config.ts +0 -223
- package/src/mcp/docs.ts +0 -154
- package/src/mcp/gateway.ts +0 -103
- package/src/mcp/lifecycle.ts +0 -79
- package/src/mcp/manager-tool.ts +0 -104
- package/src/mcp/mcpc.ts +0 -113
- package/src/mcp/registry.ts +0 -98
- package/src/mcp/triggers.ts +0 -62
- package/src/mcp/types.ts +0 -95
package/src/ui-design/session.ts
CHANGED
|
@@ -108,15 +108,19 @@ function snapshotSessionProgress(sessionDir: string): string | null {
|
|
|
108
108
|
for (const entry of entries) {
|
|
109
109
|
const absolutePath = path.join(currentDir, entry.name);
|
|
110
110
|
const relativePath = path.relative(sessionDir, absolutePath);
|
|
111
|
-
const stats = fs.statSync(absolutePath);
|
|
112
|
-
|
|
113
111
|
if (entry.isDirectory()) {
|
|
114
|
-
hash.update(
|
|
112
|
+
hash.update("dir\0");
|
|
113
|
+
hash.update(relativePath);
|
|
114
|
+
hash.update("\0");
|
|
115
115
|
visit(absolutePath);
|
|
116
116
|
continue;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
hash.update(
|
|
119
|
+
hash.update("file\0");
|
|
120
|
+
hash.update(relativePath);
|
|
121
|
+
hash.update("\0");
|
|
122
|
+
hash.update(fs.readFileSync(absolutePath));
|
|
123
|
+
hash.update("\0");
|
|
120
124
|
}
|
|
121
125
|
};
|
|
122
126
|
|
|
@@ -765,6 +769,106 @@ function discardSessionDir(sessionDir: string): void {
|
|
|
765
769
|
}
|
|
766
770
|
}
|
|
767
771
|
|
|
772
|
+
function buildCompletionRepairSteer(
|
|
773
|
+
sessionDir: string,
|
|
774
|
+
manifest: Manifest,
|
|
775
|
+
completionIssues: string[],
|
|
776
|
+
): string {
|
|
777
|
+
return manifest.backend === "pencil-mcp"
|
|
778
|
+
? REPAIR_COMPLETE_STEER_TEMPLATE_PENCIL(sessionDir, manifest.penFilePath, completionIssues)
|
|
779
|
+
: REPAIR_COMPLETE_STEER_TEMPLATE(sessionDir, completionIssues);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
function sendNoUiPauseMessage(
|
|
783
|
+
platform: Platform,
|
|
784
|
+
sessionDir: string,
|
|
785
|
+
status: ManifestStatus,
|
|
786
|
+
): void {
|
|
787
|
+
const message = [
|
|
788
|
+
`ui-design session paused with status \`${status}\` in a no-UI runtime.`,
|
|
789
|
+
`Artifacts were preserved at \`${sessionDir}\`.`,
|
|
790
|
+
"Interactive review is unavailable here. Continue manually by inspecting that directory or rerun `/supi:ui-design` in an interactive TUI.",
|
|
791
|
+
].join("\n");
|
|
792
|
+
platform.sendMessage(
|
|
793
|
+
{
|
|
794
|
+
customType: "supi-ui-design-paused-no-ui",
|
|
795
|
+
content: [{ type: "text", text: message }],
|
|
796
|
+
display: true,
|
|
797
|
+
},
|
|
798
|
+
{ deliverAs: "steer", triggerTurn: false },
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
async function handleNoUiUiDesignAgentEnd(
|
|
803
|
+
platform: Platform,
|
|
804
|
+
ctx: any,
|
|
805
|
+
session: UiDesignSession,
|
|
806
|
+
manifest: Manifest | null,
|
|
807
|
+
): Promise<void> {
|
|
808
|
+
const sessionDir = session.dir;
|
|
809
|
+
|
|
810
|
+
if (!manifest) {
|
|
811
|
+
await runCleanup();
|
|
812
|
+
ctx?.ui?.notify?.(
|
|
813
|
+
`ui-design session state is unreadable; artifacts preserved at ${sessionDir}.`,
|
|
814
|
+
"warning",
|
|
815
|
+
);
|
|
816
|
+
cancelUiDesignTracking("manifest_missing_no_ui");
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (manifest.status === "complete") {
|
|
821
|
+
const completion = validateCompletionProof(sessionDir, manifest);
|
|
822
|
+
const validatedManifest = completion.validatedManifest;
|
|
823
|
+
if (
|
|
824
|
+
!sameCritiqueSummary(manifest.critique, validatedManifest.critique) ||
|
|
825
|
+
manifest.approvedAt !== validatedManifest.approvedAt
|
|
826
|
+
) {
|
|
827
|
+
writeManifest(sessionDir, validatedManifest);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
if (completion.issues.length > 0) {
|
|
831
|
+
await resumeSession(
|
|
832
|
+
platform,
|
|
833
|
+
ctx,
|
|
834
|
+
session,
|
|
835
|
+
buildCompletionRepairSteer(sessionDir, manifest, completion.issues),
|
|
836
|
+
);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
writeManifest(sessionDir, { ...validatedManifest, acknowledged: true });
|
|
841
|
+
await runCleanup();
|
|
842
|
+
ctx?.ui?.notify?.(`ui-design complete; artifacts kept at ${sessionDir}.`, "info");
|
|
843
|
+
cancelUiDesignTracking("complete_no_ui");
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (manifest.status === "discarded") {
|
|
848
|
+
await runCleanup();
|
|
849
|
+
discardSessionDir(sessionDir);
|
|
850
|
+
cancelUiDesignTracking("discarded_no_ui");
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (
|
|
855
|
+
manifest.status === "in-progress" ||
|
|
856
|
+
manifest.status === "critiquing" ||
|
|
857
|
+
manifest.status === "awaiting-review"
|
|
858
|
+
) {
|
|
859
|
+
if (sessionMadeProgress(sessionDir)) {
|
|
860
|
+
await resumeSession(platform, ctx, session, RESUME_STEER_TEMPLATE(sessionDir));
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
sendNoUiPauseMessage(platform, sessionDir, manifest.status);
|
|
865
|
+
ctx?.ui?.notify?.(`ui-design paused; artifacts preserved at ${sessionDir}.`, "warning");
|
|
866
|
+
await runCleanup();
|
|
867
|
+
cancelUiDesignTracking("paused_no_ui");
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
|
|
768
872
|
function getUiDesignWritePaths(toolName: string, input: Record<string, unknown>): string[] | undefined {
|
|
769
873
|
switch (toolName) {
|
|
770
874
|
case "write":
|
|
@@ -784,8 +888,6 @@ function getUiDesignWritePaths(toolName: string, input: Record<string, unknown>)
|
|
|
784
888
|
: "",
|
|
785
889
|
);
|
|
786
890
|
}
|
|
787
|
-
case "notebook":
|
|
788
|
-
return [typeof input.notebook_path === "string" ? input.notebook_path : ""];
|
|
789
891
|
default:
|
|
790
892
|
return undefined;
|
|
791
893
|
}
|
|
@@ -852,11 +954,15 @@ export function registerUiDesignToolGuard(platform: Platform): void {
|
|
|
852
954
|
export function registerUiDesignApprovalHook(platform: Platform): void {
|
|
853
955
|
platform.on("agent_end", async (_event: any, ctx: any) => {
|
|
854
956
|
const session = activeSession;
|
|
855
|
-
if (!session
|
|
957
|
+
if (!session) return;
|
|
856
958
|
|
|
857
959
|
const sessionDir = session.dir;
|
|
858
960
|
const manifest = readManifest(sessionDir);
|
|
859
961
|
|
|
962
|
+
if (!ctx?.hasUI) {
|
|
963
|
+
await handleNoUiUiDesignAgentEnd(platform, ctx, session, manifest);
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
860
966
|
// Missing / unparseable manifest — unsafe to resume
|
|
861
967
|
if (!manifest) {
|
|
862
968
|
const choice = await ctx.ui.select(
|
|
@@ -890,9 +996,7 @@ export function registerUiDesignApprovalHook(platform: Platform): void {
|
|
|
890
996
|
// Pencil manifests always cite pencil artifacts in their repair steer,
|
|
891
997
|
// even when `penFilePath` is missing — the HTML template would point
|
|
892
998
|
// at files pencil sessions never produce.
|
|
893
|
-
const repairSteer = manifest.
|
|
894
|
-
? REPAIR_COMPLETE_STEER_TEMPLATE_PENCIL(sessionDir, manifest.penFilePath, completion.issues)
|
|
895
|
-
: REPAIR_COMPLETE_STEER_TEMPLATE(sessionDir, completion.issues);
|
|
999
|
+
const repairSteer = buildCompletionRepairSteer(sessionDir, manifest, completion.issues);
|
|
896
1000
|
await resumeSession(
|
|
897
1001
|
platform,
|
|
898
1002
|
ctx,
|
package/src/utils/executable.ts
CHANGED
|
@@ -36,8 +36,17 @@ function isFile(filePath: string): boolean {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
function defaultSearchPath(): string {
|
|
40
|
+
if (process.env.PATH !== undefined) {
|
|
41
|
+
return process.env.PATH;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path");
|
|
45
|
+
return pathKey ? process.env[pathKey] ?? "" : "";
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
function resolveSearchDirectories(options: ExecutableSearchOptions): string[] {
|
|
40
|
-
const pathDirs = (options.searchPath ??
|
|
49
|
+
const pathDirs = (options.searchPath ?? defaultSearchPath())
|
|
41
50
|
.split(path.delimiter)
|
|
42
51
|
.filter(Boolean);
|
|
43
52
|
const localDirs = (options.localDirs ?? []).map((dir) =>
|
|
@@ -17,7 +17,7 @@ function splitWorkspacePath(relativeDir: string): string[] {
|
|
|
17
17
|
// Team-shared (local) state: <cwd-or-repoRoot>/.omp/supipowers/<...>
|
|
18
18
|
//
|
|
19
19
|
// These paths are committed (or at least shareable) across a team clone. Used for
|
|
20
|
-
// config.json, model.json, review-agents/config.yml,
|
|
20
|
+
// config.json, model.json, review-agents/config.yml, etc.
|
|
21
21
|
// ──────────────────────────────────────────────────────────────────────────
|
|
22
22
|
|
|
23
23
|
export function getRootStateDir(paths: PlatformPaths, repoRoot: string): string {
|