@shahmarasy/prodo 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/agent-command-installer.js +5 -0
- package/dist/artifacts.js +45 -5
- package/dist/cli.js +0 -1
- package/dist/init-tui.d.ts +0 -1
- package/dist/init-tui.js +2 -14
- package/dist/providers/mock-provider.js +8 -1
- package/dist/templates.js +1 -0
- package/package.json +1 -1
- package/src/agent-command-installer.ts +5 -0
- package/src/artifacts.ts +47 -4
- package/src/cli.ts +0 -1
- package/src/init-tui.ts +2 -16
- package/src/providers/mock-provider.ts +12 -1
- package/src/templates.ts +1 -0
- package/templates/commands/prodo-normalize.md +1 -0
- package/templates/commands/prodo-prd.md +1 -1
- package/templates/commands/prodo-stories.md +1 -1
- package/templates/commands/prodo-techspec.md +1 -1
- package/templates/commands/prodo-validate.md +1 -1
- package/templates/commands/prodo-wireframe.md +1 -1
- package/templates/commands/prodo-workflow.md +1 -1
|
@@ -68,6 +68,11 @@ function toTomlPrompt(body, frontmatter, argsPlaceholder) {
|
|
|
68
68
|
return `description = "${description.replace(/"/g, '\\"')}"
|
|
69
69
|
|
|
70
70
|
prompt = """
|
|
71
|
+
Important execution rule:
|
|
72
|
+
- This is an agent slash command, not a shell command.
|
|
73
|
+
- Do NOT run \`prodo-normalize\`, \`prodo-prd\`, or \`prodo ...\` in shell.
|
|
74
|
+
- Execute the workflow directly using workspace files.
|
|
75
|
+
|
|
71
76
|
${promptBody}
|
|
72
77
|
"""`;
|
|
73
78
|
}
|
package/dist/artifacts.js
CHANGED
|
@@ -53,18 +53,53 @@ async function loadArtifactDoc(filePath) {
|
|
|
53
53
|
body: parsed.content
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
+
function languageProbe(body) {
|
|
57
|
+
const stripped = body
|
|
58
|
+
.replace(/```[\s\S]*?```/g, " ")
|
|
59
|
+
.replace(/^\s*#{1,6}\s+.*$/gm, " ")
|
|
60
|
+
.replace(/<[^>]+>/g, " ")
|
|
61
|
+
.replace(/\|/g, " ")
|
|
62
|
+
.replace(/\s+/g, " ")
|
|
63
|
+
.trim()
|
|
64
|
+
.toLowerCase();
|
|
65
|
+
return ` ${stripped} `;
|
|
66
|
+
}
|
|
56
67
|
function hasEnglishLeak(body) {
|
|
57
|
-
const englishMarkers = [" the ", " and ", " with ", " user ", " should ", " must ", " requirement ", " flow "];
|
|
58
|
-
const normalized =
|
|
68
|
+
const englishMarkers = [" the ", " and ", " with ", " user ", " should ", " must ", " requirement ", " flow ", " error ", " success "];
|
|
69
|
+
const normalized = languageProbe(body);
|
|
59
70
|
return englishMarkers.filter((m) => normalized.includes(m)).length >= 2;
|
|
60
71
|
}
|
|
72
|
+
function hasTurkishLeak(body) {
|
|
73
|
+
const turkishMarkers = [
|
|
74
|
+
" ve ",
|
|
75
|
+
" ile ",
|
|
76
|
+
" kullanici ",
|
|
77
|
+
" kullanıcı ",
|
|
78
|
+
" akis ",
|
|
79
|
+
" akış ",
|
|
80
|
+
" hata ",
|
|
81
|
+
" basari ",
|
|
82
|
+
" başarı ",
|
|
83
|
+
" ekran ",
|
|
84
|
+
" islem ",
|
|
85
|
+
" işlem ",
|
|
86
|
+
" gerekli "
|
|
87
|
+
];
|
|
88
|
+
const normalized = languageProbe(body);
|
|
89
|
+
return turkishMarkers.filter((m) => normalized.includes(m)).length >= 2;
|
|
90
|
+
}
|
|
61
91
|
function enforceLanguage(body, lang, artifactType) {
|
|
62
92
|
const normalized = (lang || "en").toLowerCase();
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
93
|
+
if (normalized.startsWith("tr")) {
|
|
94
|
+
if (!hasEnglishLeak(body))
|
|
95
|
+
return;
|
|
66
96
|
throw new errors_1.UserError(`Language enforcement failed for ${artifactType}: output contains English fragments while language is Turkish.`);
|
|
67
97
|
}
|
|
98
|
+
if (normalized.startsWith("en")) {
|
|
99
|
+
if (!hasTurkishLeak(body))
|
|
100
|
+
return;
|
|
101
|
+
throw new errors_1.UserError(`Language enforcement failed for ${artifactType}: output contains Turkish fragments while language is English.`);
|
|
102
|
+
}
|
|
68
103
|
}
|
|
69
104
|
function toSlug(value) {
|
|
70
105
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "screen";
|
|
@@ -387,6 +422,7 @@ async function writeWireframeScreens(targetDir, baseName, normalized, coverage,
|
|
|
387
422
|
return "[ LOGO ]";
|
|
388
423
|
return token;
|
|
389
424
|
});
|
|
425
|
+
enforceLanguage(html, lang, "wireframe");
|
|
390
426
|
await promises_1.default.writeFile(htmlPath, html, "utf8");
|
|
391
427
|
const defaultMap = {
|
|
392
428
|
purpose: [`- [${screen.id}] ${screen.text}`],
|
|
@@ -437,6 +473,7 @@ async function writeWireframeScreens(targetDir, baseName, normalized, coverage,
|
|
|
437
473
|
mdLines.push("");
|
|
438
474
|
}
|
|
439
475
|
const mdBody = mdLines.join("\n").trim();
|
|
476
|
+
enforceLanguage(mdBody, lang, "wireframe");
|
|
440
477
|
await promises_1.default.writeFile(mdPath, `${mdBody}\n`, "utf8");
|
|
441
478
|
if (!primaryMdPath)
|
|
442
479
|
primaryMdPath = mdPath;
|
|
@@ -519,6 +556,9 @@ async function generateArtifact(options) {
|
|
|
519
556
|
workflowMermaidBody = renderWorkflowMermaidTemplate(companionTemplate.content, normalizedBrief, contractCoverage, settings.lang).trim();
|
|
520
557
|
}
|
|
521
558
|
enforceLanguage(generatedBody, settings.lang, artifactType);
|
|
559
|
+
if (artifactType === "workflow" && workflowMermaidBody) {
|
|
560
|
+
enforceLanguage(workflowMermaidBody, settings.lang, artifactType);
|
|
561
|
+
}
|
|
522
562
|
const uncovered = missingCoverage(def.required_contracts, normalizedBrief, contractCoverage);
|
|
523
563
|
if (uncovered.length > 0) {
|
|
524
564
|
const lines = uncovered
|
package/dist/cli.js
CHANGED
package/dist/init-tui.d.ts
CHANGED
package/dist/init-tui.js
CHANGED
|
@@ -117,18 +117,6 @@ async function gatherInitSelections(options) {
|
|
|
117
117
|
clack.cancel("Initialization cancelled.");
|
|
118
118
|
throw new errors_1.UserError("Initialization cancelled.");
|
|
119
119
|
}
|
|
120
|
-
const script = await clack.select({
|
|
121
|
-
message: "Select script type",
|
|
122
|
-
initialValue: fallbackScript,
|
|
123
|
-
options: [
|
|
124
|
-
{ value: "sh", label: "sh", hint: "Command profile (metadata)" },
|
|
125
|
-
{ value: "ps", label: "ps", hint: "Command profile (metadata)" }
|
|
126
|
-
]
|
|
127
|
-
});
|
|
128
|
-
if (clack.isCancel(script)) {
|
|
129
|
-
clack.cancel("Initialization cancelled.");
|
|
130
|
-
throw new errors_1.UserError("Initialization cancelled.");
|
|
131
|
-
}
|
|
132
120
|
const lang = await clack.select({
|
|
133
121
|
message: "Select language",
|
|
134
122
|
initialValue: defaultLang,
|
|
@@ -150,12 +138,12 @@ async function gatherInitSelections(options) {
|
|
|
150
138
|
selectedAi = detectedAi;
|
|
151
139
|
return {
|
|
152
140
|
ai: selectedAi,
|
|
153
|
-
script,
|
|
141
|
+
script: fallbackScript,
|
|
154
142
|
lang,
|
|
155
143
|
interactive: true
|
|
156
144
|
};
|
|
157
145
|
}
|
|
158
146
|
function finishInitInteractive(summary) {
|
|
159
147
|
const aiText = summary.ai ?? "none";
|
|
160
|
-
return loadClack().then((clack) => clack.outro(`Scaffold complete.\nAI: ${aiText}\
|
|
148
|
+
return loadClack().then((clack) => clack.outro(`Scaffold complete.\nAI: ${aiText}\nLanguage: ${summary.lang}\nSettings: ${summary.settingsPath}\nNext: edit brief.md`));
|
|
161
149
|
}
|
|
@@ -107,8 +107,15 @@ function buildArtifactBody(schemaHint, inputContext) {
|
|
|
107
107
|
const lang = typeof inputContext.outputLanguage === "string" ? inputContext.outputLanguage.toLowerCase() : "en";
|
|
108
108
|
const items = normalizeSectionItems(inputContext);
|
|
109
109
|
const coverage = coverageItems(schemaHint, inputContext);
|
|
110
|
+
const localizedItems = lang === "tr" ? items.map((_, index) => `Gereksinim maddesi ${index + 1}`) : items;
|
|
111
|
+
const localizedCoverage = lang === "tr"
|
|
112
|
+
? coverage.map((item, index) => ({
|
|
113
|
+
id: item.id,
|
|
114
|
+
text: `Kontrat kapsami ${index + 1}`
|
|
115
|
+
}))
|
|
116
|
+
: coverage;
|
|
110
117
|
const fallback = lang === "tr" ? "Detay daha sonra netlestirilecek." : "To be refined.";
|
|
111
|
-
const sections = schemaHint.requiredHeadings.map((heading) => headingBlock(heading,
|
|
118
|
+
const sections = schemaHint.requiredHeadings.map((heading) => headingBlock(heading, localizedItems, fallback, localizedCoverage));
|
|
112
119
|
const title = lang === "tr"
|
|
113
120
|
? `# ${productName} icin ${schemaHint.artifactType.toUpperCase()}`
|
|
114
121
|
: `# ${schemaHint.artifactType.toUpperCase()} for ${productName}`;
|
package/dist/templates.js
CHANGED
|
@@ -362,6 +362,7 @@ Execution policy:
|
|
|
362
362
|
- Execute-first, diagnose-second.
|
|
363
363
|
- Perform only minimal prerequisite checks before execution.
|
|
364
364
|
- Do not run shell commands or CLI commands from inside the agent.
|
|
365
|
+
- Never run \`prodo-${command.cliSubcommand}\`, \`prodo ${command.cliSubcommand}\`, or \`prodo ...\` in shell.
|
|
365
366
|
- Do not inspect hooks or internals unless command execution fails.
|
|
366
367
|
- Input files are read-only; never modify or rewrite \`brief.md\`.
|
|
367
368
|
|
package/package.json
CHANGED
|
@@ -77,6 +77,11 @@ function toTomlPrompt(body: string, frontmatter: Record<string, unknown>, argsPl
|
|
|
77
77
|
return `description = "${description.replace(/"/g, '\\"')}"
|
|
78
78
|
|
|
79
79
|
prompt = """
|
|
80
|
+
Important execution rule:
|
|
81
|
+
- This is an agent slash command, not a shell command.
|
|
82
|
+
- Do NOT run \`prodo-normalize\`, \`prodo-prd\`, or \`prodo ...\` in shell.
|
|
83
|
+
- Execute the workflow directly using workspace files.
|
|
84
|
+
|
|
80
85
|
${promptBody}
|
|
81
86
|
"""`;
|
|
82
87
|
}
|
package/src/artifacts.ts
CHANGED
|
@@ -66,20 +66,58 @@ async function loadArtifactDoc(filePath: string): Promise<ArtifactDoc> {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function languageProbe(body: string): string {
|
|
70
|
+
const stripped = body
|
|
71
|
+
.replace(/```[\s\S]*?```/g, " ")
|
|
72
|
+
.replace(/^\s*#{1,6}\s+.*$/gm, " ")
|
|
73
|
+
.replace(/<[^>]+>/g, " ")
|
|
74
|
+
.replace(/\|/g, " ")
|
|
75
|
+
.replace(/\s+/g, " ")
|
|
76
|
+
.trim()
|
|
77
|
+
.toLowerCase();
|
|
78
|
+
return ` ${stripped} `;
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
function hasEnglishLeak(body: string): boolean {
|
|
70
|
-
const englishMarkers = [" the ", " and ", " with ", " user ", " should ", " must ", " requirement ", " flow "];
|
|
71
|
-
const normalized =
|
|
82
|
+
const englishMarkers = [" the ", " and ", " with ", " user ", " should ", " must ", " requirement ", " flow ", " error ", " success "];
|
|
83
|
+
const normalized = languageProbe(body);
|
|
72
84
|
return englishMarkers.filter((m) => normalized.includes(m)).length >= 2;
|
|
73
85
|
}
|
|
74
86
|
|
|
87
|
+
function hasTurkishLeak(body: string): boolean {
|
|
88
|
+
const turkishMarkers = [
|
|
89
|
+
" ve ",
|
|
90
|
+
" ile ",
|
|
91
|
+
" kullanici ",
|
|
92
|
+
" kullanıcı ",
|
|
93
|
+
" akis ",
|
|
94
|
+
" akış ",
|
|
95
|
+
" hata ",
|
|
96
|
+
" basari ",
|
|
97
|
+
" başarı ",
|
|
98
|
+
" ekran ",
|
|
99
|
+
" islem ",
|
|
100
|
+
" işlem ",
|
|
101
|
+
" gerekli "
|
|
102
|
+
];
|
|
103
|
+
const normalized = languageProbe(body);
|
|
104
|
+
return turkishMarkers.filter((m) => normalized.includes(m)).length >= 2;
|
|
105
|
+
}
|
|
106
|
+
|
|
75
107
|
function enforceLanguage(body: string, lang: string, artifactType: ArtifactType): void {
|
|
76
108
|
const normalized = (lang || "en").toLowerCase();
|
|
77
|
-
if (
|
|
78
|
-
|
|
109
|
+
if (normalized.startsWith("tr")) {
|
|
110
|
+
if (!hasEnglishLeak(body)) return;
|
|
79
111
|
throw new UserError(
|
|
80
112
|
`Language enforcement failed for ${artifactType}: output contains English fragments while language is Turkish.`
|
|
81
113
|
);
|
|
82
114
|
}
|
|
115
|
+
if (normalized.startsWith("en")) {
|
|
116
|
+
if (!hasTurkishLeak(body)) return;
|
|
117
|
+
throw new UserError(
|
|
118
|
+
`Language enforcement failed for ${artifactType}: output contains Turkish fragments while language is English.`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
83
121
|
}
|
|
84
122
|
|
|
85
123
|
function toSlug(value: string): string {
|
|
@@ -473,6 +511,7 @@ async function writeWireframeScreens(
|
|
|
473
511
|
return token;
|
|
474
512
|
}
|
|
475
513
|
);
|
|
514
|
+
enforceLanguage(html, lang, "wireframe");
|
|
476
515
|
await fs.writeFile(htmlPath, html, "utf8");
|
|
477
516
|
const defaultMap = {
|
|
478
517
|
purpose: [`- [${screen.id}] ${screen.text}`],
|
|
@@ -516,6 +555,7 @@ async function writeWireframeScreens(
|
|
|
516
555
|
mdLines.push("");
|
|
517
556
|
}
|
|
518
557
|
const mdBody = mdLines.join("\n").trim();
|
|
558
|
+
enforceLanguage(mdBody, lang, "wireframe");
|
|
519
559
|
await fs.writeFile(mdPath, `${mdBody}\n`, "utf8");
|
|
520
560
|
if (!primaryMdPath) primaryMdPath = mdPath;
|
|
521
561
|
summaryBodies.push(mdBody);
|
|
@@ -630,6 +670,9 @@ export async function generateArtifact(options: GenerateOptions): Promise<string
|
|
|
630
670
|
}
|
|
631
671
|
|
|
632
672
|
enforceLanguage(generatedBody, settings.lang, artifactType);
|
|
673
|
+
if (artifactType === "workflow" && workflowMermaidBody) {
|
|
674
|
+
enforceLanguage(workflowMermaidBody, settings.lang, artifactType);
|
|
675
|
+
}
|
|
633
676
|
const uncovered = missingCoverage(def.required_contracts, normalizedBrief, contractCoverage);
|
|
634
677
|
if (uncovered.length > 0) {
|
|
635
678
|
const lines = uncovered
|
package/src/cli.ts
CHANGED
package/src/init-tui.ts
CHANGED
|
@@ -140,19 +140,6 @@ export async function gatherInitSelections(options: GatherInitUiOptions): Promis
|
|
|
140
140
|
throw new UserError("Initialization cancelled.");
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
const script = await clack.select({
|
|
144
|
-
message: "Select script type",
|
|
145
|
-
initialValue: fallbackScript,
|
|
146
|
-
options: [
|
|
147
|
-
{ value: "sh", label: "sh", hint: "Command profile (metadata)" },
|
|
148
|
-
{ value: "ps", label: "ps", hint: "Command profile (metadata)" }
|
|
149
|
-
]
|
|
150
|
-
});
|
|
151
|
-
if (clack.isCancel(script)) {
|
|
152
|
-
clack.cancel("Initialization cancelled.");
|
|
153
|
-
throw new UserError("Initialization cancelled.");
|
|
154
|
-
}
|
|
155
|
-
|
|
156
143
|
const lang = await clack.select({
|
|
157
144
|
message: "Select language",
|
|
158
145
|
initialValue: defaultLang,
|
|
@@ -173,7 +160,7 @@ export async function gatherInitSelections(options: GatherInitUiOptions): Promis
|
|
|
173
160
|
|
|
174
161
|
return {
|
|
175
162
|
ai: selectedAi,
|
|
176
|
-
script,
|
|
163
|
+
script: fallbackScript,
|
|
177
164
|
lang,
|
|
178
165
|
interactive: true
|
|
179
166
|
};
|
|
@@ -183,11 +170,10 @@ export function finishInitInteractive(summary: {
|
|
|
183
170
|
projectRoot: string;
|
|
184
171
|
settingsPath: string;
|
|
185
172
|
ai?: SupportedAi;
|
|
186
|
-
script: "sh" | "ps";
|
|
187
173
|
lang: "tr" | "en";
|
|
188
174
|
}): Promise<void> {
|
|
189
175
|
const aiText = summary.ai ?? "none";
|
|
190
176
|
return loadClack().then((clack) => clack.outro(
|
|
191
|
-
`Scaffold complete.\nAI: ${aiText}\
|
|
177
|
+
`Scaffold complete.\nAI: ${aiText}\nLanguage: ${summary.lang}\nSettings: ${summary.settingsPath}\nNext: edit brief.md`
|
|
192
178
|
));
|
|
193
179
|
}
|
|
@@ -120,8 +120,19 @@ function buildArtifactBody(schemaHint: ProviderSchemaHint, inputContext: Record<
|
|
|
120
120
|
const lang = typeof inputContext.outputLanguage === "string" ? inputContext.outputLanguage.toLowerCase() : "en";
|
|
121
121
|
const items = normalizeSectionItems(inputContext);
|
|
122
122
|
const coverage = coverageItems(schemaHint, inputContext);
|
|
123
|
+
const localizedItems =
|
|
124
|
+
lang === "tr" ? items.map((_, index) => `Gereksinim maddesi ${index + 1}`) : items;
|
|
125
|
+
const localizedCoverage =
|
|
126
|
+
lang === "tr"
|
|
127
|
+
? coverage.map((item, index) => ({
|
|
128
|
+
id: item.id,
|
|
129
|
+
text: `Kontrat kapsami ${index + 1}`
|
|
130
|
+
}))
|
|
131
|
+
: coverage;
|
|
123
132
|
const fallback = lang === "tr" ? "Detay daha sonra netlestirilecek." : "To be refined.";
|
|
124
|
-
const sections = schemaHint.requiredHeadings.map((heading) =>
|
|
133
|
+
const sections = schemaHint.requiredHeadings.map((heading) =>
|
|
134
|
+
headingBlock(heading, localizedItems, fallback, localizedCoverage)
|
|
135
|
+
);
|
|
125
136
|
const title =
|
|
126
137
|
lang === "tr"
|
|
127
138
|
? `# ${productName} icin ${schemaHint.artifactType.toUpperCase()}`
|
package/src/templates.ts
CHANGED
|
@@ -372,6 +372,7 @@ Execution policy:
|
|
|
372
372
|
- Execute-first, diagnose-second.
|
|
373
373
|
- Perform only minimal prerequisite checks before execution.
|
|
374
374
|
- Do not run shell commands or CLI commands from inside the agent.
|
|
375
|
+
- Never run \`prodo-${command.cliSubcommand}\`, \`prodo ${command.cliSubcommand}\`, or \`prodo ...\` in shell.
|
|
375
376
|
- Do not inspect hooks or internals unless command execution fails.
|
|
376
377
|
- Input files are read-only; never modify or rewrite \`brief.md\`.
|
|
377
378
|
|
|
@@ -11,6 +11,7 @@ $ARGUMENTS
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
13
|
- Do not run shell/CLI commands from inside the agent.
|
|
14
|
+
- Never run `prodo-normalize`, `prodo normalize`, or `prodo ...` in shell.
|
|
14
15
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
16
|
|
|
16
17
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-prd`, `prodo prd`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-stories`, `prodo stories`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-techspec`, `prodo techspec`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-validate`, `prodo validate`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-wireframe`, `prodo wireframe`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|
|
@@ -10,7 +10,7 @@ $ARGUMENTS
|
|
|
10
10
|
|
|
11
11
|
Execution policy:
|
|
12
12
|
- Execute-first, diagnose-second.
|
|
13
|
-
- Do not run shell/CLI commands from inside the agent.
|
|
13
|
+
- Do not run shell/CLI commands from inside the agent.`n- Never run `prodo-workflow`, `prodo workflow`, or `prodo ...` in shell.
|
|
14
14
|
- Input files are read-only; never modify or rewrite `brief.md`.
|
|
15
15
|
|
|
16
16
|
## Execution
|