gsd-pi 2.38.0-dev.96dc7fb → 2.38.0-dev.bc2e21e
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/app-paths.js +1 -1
- package/dist/extension-registry.js +2 -2
- package/dist/remote-questions-config.js +2 -2
- package/dist/resources/extensions/env-utils.js +29 -0
- package/dist/resources/extensions/get-secrets-from-user.js +5 -24
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +7 -8
- package/dist/resources/extensions/gsd/auto-loop.js +54 -30
- package/dist/resources/extensions/gsd/auto-post-unit.js +75 -71
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +10 -26
- package/dist/resources/extensions/gsd/commands-extensions.js +3 -2
- package/dist/resources/extensions/gsd/commands.js +2 -1
- package/dist/resources/extensions/gsd/detection.js +1 -2
- package/dist/resources/extensions/gsd/export.js +1 -1
- package/dist/resources/extensions/gsd/files.js +2 -2
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/index.js +2 -1
- package/dist/resources/extensions/gsd/migrate/parsers.js +1 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +1 -1
- package/dist/resources/extensions/gsd/preferences.js +4 -3
- package/dist/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -8
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/dist/resources/extensions/gsd/prompts/run-uat.md +25 -10
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +2 -1
- package/dist/resources/extensions/gsd/resource-version.js +2 -1
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/visualizer-data.js +1 -1
- package/dist/resources/extensions/remote-questions/status.js +2 -1
- package/dist/resources/extensions/remote-questions/store.js +2 -1
- package/dist/resources/extensions/search-the-web/provider.js +2 -1
- package/dist/resources/extensions/subagent/isolation.js +2 -1
- package/dist/resources/extensions/ttsr/rule-loader.js +2 -1
- package/package.json +1 -1
- package/src/resources/extensions/env-utils.ts +31 -0
- package/src/resources/extensions/get-secrets-from-user.ts +5 -24
- package/src/resources/extensions/gsd/auto/session.ts +5 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +6 -8
- package/src/resources/extensions/gsd/auto-loop.ts +70 -63
- package/src/resources/extensions/gsd/auto-post-unit.ts +52 -42
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +3 -1
- package/src/resources/extensions/gsd/auto.ts +14 -29
- package/src/resources/extensions/gsd/commands-extensions.ts +4 -2
- package/src/resources/extensions/gsd/commands.ts +3 -1
- package/src/resources/extensions/gsd/detection.ts +2 -2
- package/src/resources/extensions/gsd/export.ts +1 -1
- package/src/resources/extensions/gsd/files.ts +2 -2
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/index.ts +3 -1
- package/src/resources/extensions/gsd/migrate/parsers.ts +1 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +1 -1
- package/src/resources/extensions/gsd/preferences.ts +5 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +4 -8
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/src/resources/extensions/gsd/prompts/run-uat.md +25 -10
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +3 -1
- package/src/resources/extensions/gsd/resource-version.ts +3 -1
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +11 -3
- package/src/resources/extensions/gsd/visualizer-data.ts +1 -1
- package/src/resources/extensions/remote-questions/status.ts +3 -1
- package/src/resources/extensions/remote-questions/store.ts +3 -1
- package/src/resources/extensions/search-the-web/provider.ts +2 -1
- package/src/resources/extensions/subagent/isolation.ts +3 -1
- package/src/resources/extensions/ttsr/rule-loader.ts +3 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const promptsDir = join(process.cwd(), "src/resources/extensions/gsd/prompts");
|
|
7
|
+
|
|
8
|
+
function readPrompt(name: string): string {
|
|
9
|
+
return readFileSync(join(promptsDir, `${name}.md`), "utf-8");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test("reactive-execute prompt keeps task summaries with subagents and avoids batch commits", () => {
|
|
13
|
+
const prompt = readPrompt("reactive-execute");
|
|
14
|
+
assert.match(prompt, /subagent-written summary as authoritative/i);
|
|
15
|
+
assert.match(prompt, /Do NOT create a batch commit/i);
|
|
16
|
+
assert.doesNotMatch(prompt, /\*\*Write task summaries\*\*/i);
|
|
17
|
+
assert.doesNotMatch(prompt, /\*\*Commit\*\* all changes/i);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("run-uat prompt branches on dynamic UAT mode and supports runtime evidence", () => {
|
|
21
|
+
const prompt = readPrompt("run-uat");
|
|
22
|
+
assert.match(prompt, /\*\*Detected UAT mode:\*\*\s*`\{\{uatType\}\}`/);
|
|
23
|
+
assert.match(prompt, /uatType:\s*\{\{uatType\}\}/);
|
|
24
|
+
assert.match(prompt, /live-runtime/);
|
|
25
|
+
assert.match(prompt, /browser\/runtime\/network/i);
|
|
26
|
+
assert.match(prompt, /NEEDS-HUMAN/);
|
|
27
|
+
assert.doesNotMatch(prompt, /uatType:\s*artifact-driven/);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("workflow-start prompt defaults to autonomy instead of per-phase confirmation", () => {
|
|
31
|
+
const prompt = readPrompt("workflow-start");
|
|
32
|
+
assert.match(prompt, /Keep moving by default/i);
|
|
33
|
+
assert.match(prompt, /Decision gates, not ceremony/i);
|
|
34
|
+
assert.doesNotMatch(prompt, /confirm with the user before proceeding/i);
|
|
35
|
+
assert.doesNotMatch(prompt, /Gate between phases/i);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("discuss prompt allows implementation questions when they materially matter", () => {
|
|
39
|
+
const prompt = readPrompt("discuss");
|
|
40
|
+
assert.match(prompt, /Lead with experience, but ask implementation when it materially matters/i);
|
|
41
|
+
assert.match(prompt, /one gate, not two/i);
|
|
42
|
+
assert.doesNotMatch(prompt, /Questions must be about the experience, not the implementation/i);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("guided discussion prompts avoid wrap-up prompts after every round", () => {
|
|
46
|
+
const milestonePrompt = readPrompt("guided-discuss-milestone");
|
|
47
|
+
const slicePrompt = readPrompt("guided-discuss-slice");
|
|
48
|
+
assert.match(milestonePrompt, /Do \*\*not\*\* ask a meta "ready to wrap up\?" question after every round/i);
|
|
49
|
+
assert.match(slicePrompt, /Do \*\*not\*\* ask a meta "ready to wrap up\?" question after every round/i);
|
|
50
|
+
assert.doesNotMatch(milestonePrompt, /I think I have a solid picture of this milestone\. Ready to wrap up/i);
|
|
51
|
+
assert.doesNotMatch(slicePrompt, /I think I have a solid picture of this slice\. Ready to wrap up/i);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("guided-resume-task prompt preserves recovery state until work is superseded", () => {
|
|
55
|
+
const prompt = readPrompt("guided-resume-task");
|
|
56
|
+
assert.match(prompt, /Do \*\*not\*\* delete the continue file immediately/i);
|
|
57
|
+
assert.match(prompt, /successfully completed or you have written a newer summary\/continue artifact/i);
|
|
58
|
+
assert.doesNotMatch(prompt, /Delete the continue file after reading it/i);
|
|
59
|
+
});
|
|
@@ -210,7 +210,7 @@ async function main(): Promise<void> {
|
|
|
210
210
|
const sliceId = 'S01';
|
|
211
211
|
const uatPath = '.gsd/milestones/M001/slices/S01/S01-UAT.md';
|
|
212
212
|
const uatResultPath = '.gsd/milestones/M001/slices/S01/S01-UAT-RESULT.md';
|
|
213
|
-
const uatType = '
|
|
213
|
+
const uatType = 'live-runtime';
|
|
214
214
|
const inlinedContext = '<!-- no context -->';
|
|
215
215
|
|
|
216
216
|
let promptResult: string | undefined;
|
|
@@ -246,13 +246,21 @@ async function main(): Promise<void> {
|
|
|
246
246
|
promptResult?.includes(uatResultPath) ?? false,
|
|
247
247
|
`prompt contains uatResultPath value after substitution`,
|
|
248
248
|
);
|
|
249
|
+
assertTrue(
|
|
250
|
+
promptResult?.includes(`Detected UAT mode:** \`${uatType}\``) ?? false,
|
|
251
|
+
`prompt contains detected dynamic uatType value "${uatType}" after substitution`,
|
|
252
|
+
);
|
|
253
|
+
assertTrue(
|
|
254
|
+
promptResult?.includes(`uatType: ${uatType}`) ?? false,
|
|
255
|
+
`prompt contains dynamic uatType frontmatter value "${uatType}" after substitution`,
|
|
256
|
+
);
|
|
249
257
|
assertTrue(
|
|
250
258
|
!/\{\{[^}]+\}\}/.test(promptResult ?? ''),
|
|
251
259
|
'no unreplaced {{...}} tokens remain after variable substitution',
|
|
252
260
|
);
|
|
253
261
|
assertTrue(
|
|
254
|
-
/
|
|
255
|
-
'prompt contains
|
|
262
|
+
/browser|runtime|execute|run/i.test(promptResult ?? ''),
|
|
263
|
+
'prompt contains runtime execution language (browser/runtime/execute/run)',
|
|
256
264
|
);
|
|
257
265
|
assertTrue(
|
|
258
266
|
!/surfaced for human review/i.test(promptResult ?? ''),
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
4
4
|
import { deriveState } from './state.js';
|
|
5
5
|
import { parseRoadmap, parsePlan, parseSummary, loadFile } from './files.js';
|
|
6
|
-
import { findMilestoneIds } from './
|
|
6
|
+
import { findMilestoneIds } from './milestone-ids.js';
|
|
7
7
|
import { resolveMilestoneFile, resolveSliceFile, resolveGsdRootFile } from './paths.js';
|
|
8
8
|
import {
|
|
9
9
|
getLedger,
|
|
@@ -7,6 +7,8 @@ import { join } from "node:path";
|
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { readPromptRecord } from "./store.js";
|
|
9
9
|
|
|
10
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
11
|
+
|
|
10
12
|
export interface LatestPromptSummary {
|
|
11
13
|
id: string;
|
|
12
14
|
status: string;
|
|
@@ -14,7 +16,7 @@ export interface LatestPromptSummary {
|
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export function getLatestPromptSummary(): LatestPromptSummary | null {
|
|
17
|
-
const runtimeDir = join(
|
|
19
|
+
const runtimeDir = join(gsdHome, "runtime", "remote-questions");
|
|
18
20
|
if (!existsSync(runtimeDir)) return null;
|
|
19
21
|
const files = readdirSync(runtimeDir).filter((f) => f.endsWith(".json"));
|
|
20
22
|
if (files.length === 0) return null;
|
|
@@ -7,8 +7,10 @@ import { join } from "node:path";
|
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import type { RemotePrompt, RemotePromptRecord, RemotePromptRef, RemoteAnswer, RemotePromptStatus } from "./types.js";
|
|
9
9
|
|
|
10
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
11
|
+
|
|
10
12
|
function runtimeDir(): string {
|
|
11
|
-
return join(
|
|
13
|
+
return join(gsdHome, "runtime", "remote-questions");
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
function recordPath(id: string): string {
|
|
@@ -17,7 +17,8 @@ import { resolveSearchProviderFromPreferences } from '../gsd/preferences.js'
|
|
|
17
17
|
// Compute authFilePath locally instead of importing from app-paths.ts,
|
|
18
18
|
// because extensions are copied to ~/.gsd/agent/extensions/ at runtime
|
|
19
19
|
// where the relative import '../../../app-paths.ts' doesn't resolve.
|
|
20
|
-
const
|
|
20
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), '.gsd')
|
|
21
|
+
const authFilePath = join(gsdHome, 'agent', 'auth.json')
|
|
21
22
|
|
|
22
23
|
export type SearchProvider = 'tavily' | 'brave' | 'ollama'
|
|
23
24
|
export type SearchProviderPreference = SearchProvider | 'auto'
|
|
@@ -57,8 +57,10 @@ function encodeCwd(cwd: string): string {
|
|
|
57
57
|
return cwd.replace(/\//g, "--");
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
const gsdHome = process.env.GSD_HOME || path.join(os.homedir(), ".gsd");
|
|
61
|
+
|
|
60
62
|
function getIsolationBaseDir(cwd: string, taskId: string): string {
|
|
61
|
-
return path.join(
|
|
63
|
+
return path.join(gsdHome, "wt", encodeCwd(cwd), taskId);
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
// Track active isolation dirs for cleanup on exit
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import { readdirSync, readFileSync, existsSync } from "node:fs";
|
|
9
9
|
import { join, basename } from "node:path";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
|
+
|
|
12
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
11
13
|
import type { Rule } from "./ttsr-manager.js";
|
|
12
14
|
import { splitFrontmatter, parseFrontmatterMap } from "../shared/frontmatter.js";
|
|
13
15
|
|
|
@@ -59,7 +61,7 @@ function scanDir(dir: string): Rule[] {
|
|
|
59
61
|
* Project rules override global rules with the same name.
|
|
60
62
|
*/
|
|
61
63
|
export function loadRules(cwd: string): Rule[] {
|
|
62
|
-
const globalDir = join(
|
|
64
|
+
const globalDir = join(gsdHome, "agent", "rules");
|
|
63
65
|
const projectDir = join(cwd, ".gsd", "rules");
|
|
64
66
|
|
|
65
67
|
const globalRules = scanDir(globalDir);
|