Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/suggest-new-tickets-preset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gemstack/framework": minor
---

Add the "Suggest new tickets" preset (#462), the Agentic PM ideation prompt. Like the other presets it prefills the dashboard editor and runs as a `prompt` kind. Per #674 the prompt is a single line, "Suggest new tickets": the run-start context fragment (#683) already points the agent at the existing `tickets/**.md` and the `.the-framework/ticketing-format.md` spec (#684), so it does not need to re-teach the ticket format or spell out the flow. Per the settled #624 model the proposal is just a PR: merging accepts the tickets, closing rejects them.
2 changes: 2 additions & 0 deletions packages/framework-dashboard/components/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
renderMaintainabilityPrompt,
renderSecurityAuditPrompt,
renderUxPrompt,
renderSuggestNewTicketsPrompt,
} from '@gemstack/framework/client'
import { usePreferences, updatePreferences, autopilotEnabled } from '../lib/preferences.js'
import { PromptEditor, type PromptEditorHandle } from './PromptEditor.js'
Expand All @@ -24,6 +25,7 @@ const PRESETS: { id: string; label: string; render: () => string }[] = [
{ id: 'maintainability', label: 'Maintainability', render: renderMaintainabilityPrompt },
{ id: 'security-audit', label: 'Security audit', render: renderSecurityAuditPrompt },
{ id: 'ux', label: 'UX', render: renderUxPrompt },
{ id: 'suggest-new-tickets', label: 'Suggest new tickets', render: renderSuggestNewTicketsPrompt },
]

// The agent + model tree (#650/#656/#658): each agent lists ONLY its own models, since `--model`
Expand Down
1 change: 1 addition & 0 deletions packages/framework/prompts/presets/suggest_new_tickets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Suggest new tickets
1 change: 1 addition & 0 deletions packages/framework/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export { renderReadabilityPrompt } from './readability-preset.js'
export { renderMaintainabilityPrompt } from './maintainability-preset.js'
export { renderSecurityAuditPrompt } from './security-audit-preset.js'
export { renderUxPrompt } from './ux-preset.js'
export { renderSuggestNewTicketsPrompt } from './suggest-new-tickets-preset.js'
6 changes: 6 additions & 0 deletions packages/framework/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ export {
UX_PROMPT_TEMPLATE,
UX_PARAMS,
} from './ux-preset.js'
export {
renderSuggestNewTicketsPrompt,
SUGGEST_NEW_TICKETS_PRESET_NAME,
SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE,
SUGGEST_NEW_TICKETS_PARAMS,
} from './suggest-new-tickets-preset.js'
export {
PRESETS,
PRESET_DIR,
Expand Down
21 changes: 21 additions & 0 deletions packages/framework/src/suggest-new-tickets-preset.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { strict as assert } from 'node:assert'
import { test } from 'node:test'
import {
renderSuggestNewTicketsPrompt,
SUGGEST_NEW_TICKETS_PARAMS,
SUGGEST_NEW_TICKETS_PRESET_NAME,
SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE,
} from './suggest-new-tickets-preset.js'

test('the Suggest-new-tickets preset is the single #674 line, with no params', () => {
assert.equal(SUGGEST_NEW_TICKETS_PRESET_NAME, 'suggest-new-tickets')
// Rom's #674 call: one line, the ambient #683/#684 context carries the ticket format + flow.
assert.equal(SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE, 'Suggest new tickets')
// Paramless: nothing to fill, and no leftover `${{ ... }}` blank.
assert.deepEqual(SUGGEST_NEW_TICKETS_PARAMS, [])
assert.equal(SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE.includes('${{'), false)
})

test('renderSuggestNewTicketsPrompt returns the template verbatim', () => {
assert.equal(renderSuggestNewTicketsPrompt(), 'Suggest new tickets')
})
27 changes: 27 additions & 0 deletions packages/framework/src/suggest-new-tickets-preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { PRESETS_SUGGEST_NEW_TICKETS } from './prompts.generated.js'

/**
* The [Suggest new tickets] preset (#462): the Agentic PM ideation prompt, shipped like the
* other presets as a direct interactive prompt rather than a build run. Per Rom's #674 call it
* is a single line — "Suggest new tickets" — and lets the ambient context carry the rest: the
* #683 run-start context fragment already points the agent at the existing `tickets/**.md` and
* the #684 `.the-framework/ticketing-format.md` spec, so the prompt does not re-teach the ticket
* format or spell out the flow. That is the #674 fix: an over-specified prompt is babysitting,
* which is brittle and counter-productive. Per the settled #624 model the proposal IS the PR:
* merging accepts the tickets, closing rejects them, so there is no separate proposal store.
*
* It has no params: the dashboard prefills this one line into the editor and the user edits it
* freely (e.g. to scope the ideation), so there is no `${{ tf.params.what }}` blank to render.
*/

/** The preset's run-kind name, as the dashboard button uses it. */
export const SUGGEST_NEW_TICKETS_PRESET_NAME = 'suggest-new-tickets'

/** The prompt, from `prompts/presets/suggest_new_tickets.md`: a single line by #674 design. */
export const SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE = PRESETS_SUGGEST_NEW_TICKETS

/** No user params: the whole prompt is the one line, so there is nothing to fill. */
export const SUGGEST_NEW_TICKETS_PARAMS: readonly [] = []

/** Render the prompt. Paramless, so it is the template verbatim. */
export const renderSuggestNewTicketsPrompt = (): string => SUGGEST_NEW_TICKETS_PROMPT_TEMPLATE
Loading