@kurokeita/add-skill 2.6.1 → 3.0.1
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 +43 -64
- package/dist/bin/cli.js +270 -478
- package/dist/skills/statusline-setup/.claude-plugin/plugin.json +1 -1
- package/dist/skills/statusline-setup/SKILL.md +48 -448
- package/dist/skills/statusline-setup/mod/hooks/register.tsx +93 -103
- package/dist/skills/statusline-setup/mod/tests/work.test.ts +28 -10
- package/dist/skills/statusline-setup/mod/types/index.d.ts +2 -1
- package/dist/skills/universalize-agents/reference/mapping.md +3 -2
- package/package.json +3 -3
- package/dist/agents/backend-specialist.md +0 -277
- package/dist/agents/code-archaeologist.md +0 -114
- package/dist/agents/database-architect.md +0 -238
- package/dist/agents/debugger.md +0 -231
- package/dist/agents/devops-engineer.md +0 -242
- package/dist/agents/documentation-writer.md +0 -104
- package/dist/agents/explorer-agent.md +0 -79
- package/dist/agents/frontend-specialist.md +0 -594
- package/dist/agents/game-developer.md +0 -162
- package/dist/agents/mobile-developer.md +0 -383
- package/dist/agents/orchestrator.md +0 -435
- package/dist/agents/penetration-tester.md +0 -188
- package/dist/agents/performance-optimizer.md +0 -191
- package/dist/agents/product-manager.md +0 -122
- package/dist/agents/product-owner.md +0 -106
- package/dist/agents/project-planner.md +0 -408
- package/dist/agents/qa-automation-engineer.md +0 -109
- package/dist/agents/security-auditor.md +0 -171
- package/dist/agents/test-engineer.md +0 -158
- package/dist/skills/agent-identifier/SKILL.md +0 -431
- package/dist/skills/agent-identifier/examples/agent-creation-prompt.md +0 -247
- package/dist/skills/agent-identifier/examples/complete-agent-examples.md +0 -432
- package/dist/skills/agent-identifier/references/agent-creation-system-prompt.md +0 -215
- package/dist/skills/agent-identifier/references/system-prompt-design.md +0 -419
- package/dist/skills/agent-identifier/references/triggering-examples.md +0 -508
- package/dist/skills/agent-identifier/scripts/validate-agent.sh +0 -217
- package/dist/skills/code-review-excellence/SKILL.md +0 -525
- package/dist/skills/component-refactoring/SKILL.md +0 -492
- package/dist/skills/component-refactoring/references/complexity-patterns.md +0 -493
- package/dist/skills/component-refactoring/references/component-splitting.md +0 -477
- package/dist/skills/component-refactoring/references/hook-extraction.md +0 -317
- package/dist/skills/context7-guidelines/SKILL.md +0 -31
- package/dist/skills/feature-design-assistant/SKILL.md +0 -371
- package/dist/skills/find-bugs/SKILL.md +0 -75
- package/dist/skills/frontend-design/SKILL.md +0 -45
- package/dist/skills/go-concurrency-patterns/SKILL.md +0 -657
- package/dist/skills/grill-me/SKILL.md +0 -9
- package/dist/skills/handoff/SKILL.md +0 -16
- package/dist/skills/koreader-plugin-development/SKILL.md +0 -141
- package/dist/skills/koreader-plugin-development/examples/2-example-patch.lua +0 -17
- package/dist/skills/koreader-plugin-development/examples/_meta.lua +0 -6
- package/dist/skills/koreader-plugin-development/examples/helloworld.lua +0 -36
- package/dist/skills/koreader-plugin-development/references/debugging.md +0 -92
- package/dist/skills/koreader-plugin-development/references/events-and-widgets.md +0 -102
- package/dist/skills/koreader-plugin-development/references/patches.md +0 -118
- package/dist/skills/koreader-plugin-development/references/plugin-anatomy.md +0 -97
- package/dist/skills/make-instruction/SKILL.md +0 -68
- package/dist/skills/make-prompt/SKILL.md +0 -70
- package/dist/skills/make-skill/SKILL.md +0 -147
- package/dist/skills/prd-to-tasks/SKILL.md +0 -164
- package/dist/skills/react-native-async-patterns/SKILL.md +0 -256
- package/dist/skills/react-native-performance/SKILL.md +0 -425
- package/dist/skills/react-native-testing/SKILL.md +0 -458
- package/dist/skills/react-native-zustand-patterns/SKILL.md +0 -343
- package/dist/skills/skill-creator/SKILL.md +0 -385
- package/dist/skills/skill-creator/scripts/init_skill.cjs +0 -235
- package/dist/skills/skill-creator/scripts/package_skill.cjs +0 -84
- package/dist/skills/skill-creator/scripts/validate_skill.cjs +0 -127
- package/dist/skills/skill-development/SKILL.md +0 -676
- package/dist/skills/skill-development/references/skill-creator-original.md +0 -210
- package/dist/skills/sql-optimization-patterns/SKILL.md +0 -509
- package/dist/skills/test-driven-development/SKILL.md +0 -114
- package/dist/skills/test-driven-development/deep-modules.md +0 -33
- package/dist/skills/test-driven-development/interface-design.md +0 -35
- package/dist/skills/test-driven-development/mocking.md +0 -68
- package/dist/skills/test-driven-development/refactoring.md +0 -10
- package/dist/skills/test-driven-development/tests.md +0 -61
- package/dist/skills/vercel-react-best-practices/AGENTS.md +0 -2410
- package/dist/skills/vercel-react-best-practices/SKILL.md +0 -127
- package/dist/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/dist/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -49
- package/dist/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/dist/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
- package/dist/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -36
- package/dist/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/dist/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/dist/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/dist/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/dist/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/dist/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/dist/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/dist/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/dist/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/dist/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/dist/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/dist/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -82
- package/dist/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/dist/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/dist/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/dist/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/dist/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/dist/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/dist/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/dist/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -50
- package/dist/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/dist/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/dist/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/dist/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/dist/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/dist/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/dist/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/dist/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/dist/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/dist/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/dist/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/dist/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/dist/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/dist/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/dist/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/dist/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/dist/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/dist/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/dist/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/dist/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/dist/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/dist/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/dist/skills/web-design-guidelines/SKILL.md +0 -40
- package/dist/skills/workflow-patterns/SKILL.md +0 -623
- package/dist/skills/write-prd/SKILL.md +0 -162
- package/dist/workflows/brainstorm.md +0 -113
- package/dist/workflows/create.md +0 -60
- package/dist/workflows/debug.md +0 -107
- package/dist/workflows/deploy.md +0 -178
- package/dist/workflows/enhance.md +0 -64
- package/dist/workflows/github-pull-request-create.md +0 -134
- package/dist/workflows/orchestrate.md +0 -246
- package/dist/workflows/plan.md +0 -90
- package/dist/workflows/preview.md +0 -83
- package/dist/workflows/status.md +0 -87
- package/dist/workflows/test.md +0 -144
- package/dist/workflows/ui-ux-pro-max.md +0 -315
|
@@ -12,22 +12,21 @@ import {
|
|
|
12
12
|
} from "./discover"
|
|
13
13
|
import { fetchAzure, fetchGitHub, git, type Run } from "./fetch"
|
|
14
14
|
|
|
15
|
-
const PANE = "work-
|
|
16
|
-
const branches = atom({ plugin: "work-
|
|
17
|
-
const work = atom({ plugin: "work-
|
|
15
|
+
const PANE = "work-pane"
|
|
16
|
+
const branches = atom({ plugin: "work-pane", key: "branches" } as const, [])
|
|
17
|
+
const work = atom({ plugin: "work-pane", key: "work" } as const, null)
|
|
18
18
|
const isFetching = atom(
|
|
19
|
-
{ plugin: "work-
|
|
19
|
+
{ plugin: "work-pane", key: "isFetching" } as const,
|
|
20
20
|
false,
|
|
21
21
|
)
|
|
22
|
-
const summary = atom({ plugin: "work-
|
|
22
|
+
const summary = atom({ plugin: "work-pane", key: "summary" } as const, null)
|
|
23
23
|
const isSummarizing = atom(
|
|
24
|
-
{ plugin: "work-
|
|
24
|
+
{ plugin: "work-pane", key: "isSummarizing" } as const,
|
|
25
25
|
false,
|
|
26
26
|
)
|
|
27
|
-
const collapsed = atom({ plugin: "work-
|
|
27
|
+
const collapsed = atom({ plugin: "work-pane", key: "collapsed" } as const, [])
|
|
28
28
|
|
|
29
29
|
let isFetchRunning = false
|
|
30
|
-
let isAutoOpenWanted = false
|
|
31
30
|
let isAutoOpened = false
|
|
32
31
|
// Which conversation this process shows, and whether a prompt was sent in it here.
|
|
33
32
|
let watchedId = ""
|
|
@@ -83,7 +82,7 @@ async function refreshWork($: EngineInterface) {
|
|
|
83
82
|
prs: [],
|
|
84
83
|
items: [],
|
|
85
84
|
fetchedAt: Date.now(),
|
|
86
|
-
|
|
85
|
+
isUnsupported: true,
|
|
87
86
|
}))
|
|
88
87
|
return
|
|
89
88
|
}
|
|
@@ -145,26 +144,10 @@ async function summarizeIfMissing($: EngineInterface) {
|
|
|
145
144
|
if (!current || "error" in current) await summarize($)
|
|
146
145
|
}
|
|
147
146
|
|
|
148
|
-
// Opens the pane once in a resumed session, the first time it has a PR or item.
|
|
149
|
-
async function autoOpen($: EngineInterface) {
|
|
150
|
-
if (!isAutoOpenWanted || isAutoOpened) return
|
|
151
|
-
await refreshWork($)
|
|
152
|
-
const current = await read($, work)
|
|
153
|
-
if (
|
|
154
|
-
isAutoOpened ||
|
|
155
|
-
!current ||
|
|
156
|
-
current.prs.length + current.items.length === 0
|
|
157
|
-
)
|
|
158
|
-
return
|
|
159
|
-
isAutoOpened = true
|
|
160
|
-
// No focus: the prompt keeps the keyboard. Ctrl+X Tab or a click focuses it to scroll.
|
|
161
|
-
await $.ui.open({ id: PANE, title: "Work", columns: 64 })
|
|
162
|
-
await summarizeIfMissing($)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
147
|
// A conversation is resumed when it has turns no prompt of this process made:
|
|
166
148
|
// --resume and --continue load them before session.start, while the picker and
|
|
167
149
|
// an in-session /resume load them later, under a new session id.
|
|
150
|
+
// A resumed conversation opens the pane once, whether or not it has a PR or item.
|
|
168
151
|
async function checkResumed($: EngineInterface) {
|
|
169
152
|
const id = await $.session.id()
|
|
170
153
|
if (id !== watchedId) {
|
|
@@ -172,16 +155,17 @@ async function checkResumed($: EngineInterface) {
|
|
|
172
155
|
// A /clear starts its conversation here, though the transcript's /clear row counts as a turn.
|
|
173
156
|
hasPromptedHere = isClearPending
|
|
174
157
|
isClearPending = false
|
|
175
|
-
isAutoOpenWanted = false
|
|
176
158
|
isAutoOpened = false
|
|
177
159
|
// Another conversation now: its branches start over from here.
|
|
178
160
|
sessionStartedAt = Date.now()
|
|
179
161
|
await update($, branches, () => [])
|
|
180
162
|
}
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
163
|
+
if (isAutoOpened || hasPromptedHere || (await $.session.turns()) === 0) return
|
|
164
|
+
isAutoOpened = true
|
|
165
|
+
void refreshWork($)
|
|
166
|
+
// No focus: the prompt keeps the keyboard. Ctrl+X Tab or a click focuses it to scroll.
|
|
167
|
+
await $.ui.open({ id: PANE, title: "Work", columns: 64 })
|
|
168
|
+
await summarizeIfMissing($)
|
|
185
169
|
}
|
|
186
170
|
|
|
187
171
|
function ago(at: number): string {
|
|
@@ -239,7 +223,6 @@ export const register: Register = (on) => {
|
|
|
239
223
|
// and moves its goal and steps on.
|
|
240
224
|
void (async () => {
|
|
241
225
|
await noteBranch($)
|
|
242
|
-
if (isAutoOpenWanted && !isAutoOpened) return autoOpen($)
|
|
243
226
|
if (await isPaneOpen($)) await Promise.all([refreshWork($), summarize($)])
|
|
244
227
|
})()
|
|
245
228
|
|
|
@@ -292,6 +275,7 @@ export const register: Register = (on) => {
|
|
|
292
275
|
)
|
|
293
276
|
const prs = current?.prs ?? []
|
|
294
277
|
const items = current?.items ?? []
|
|
278
|
+
const hasWork = !current?.isUnsupported
|
|
295
279
|
|
|
296
280
|
return (
|
|
297
281
|
<Box flexDirection="column" rowGap={1}>
|
|
@@ -331,78 +315,82 @@ export const register: Register = (on) => {
|
|
|
331
315
|
</Box>
|
|
332
316
|
)}
|
|
333
317
|
|
|
334
|
-
|
|
335
|
-
<
|
|
336
|
-
<Text
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
318
|
+
{hasWork && (
|
|
319
|
+
<Box flexDirection="column">
|
|
320
|
+
<Text>
|
|
321
|
+
<Text bold color="planMode">
|
|
322
|
+
Pull requests
|
|
323
|
+
</Text>
|
|
324
|
+
<Text dimColor>
|
|
325
|
+
{" "}
|
|
326
|
+
{prs.length}
|
|
327
|
+
{fetching ? " · updating…" : ""}
|
|
328
|
+
</Text>
|
|
343
329
|
</Text>
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
330
|
+
{current?.error && <Text color="error">{current.error}</Text>}
|
|
331
|
+
{prs.length === 0 && !current?.error && (
|
|
332
|
+
<Text dimColor>None found for this session yet.</Text>
|
|
333
|
+
)}
|
|
334
|
+
{prs.map((pr) => (
|
|
335
|
+
<Box flexDirection="column">
|
|
336
|
+
<Box flexDirection="row" columnGap={1}>
|
|
337
|
+
<Button
|
|
338
|
+
key={`toggle-${pr.number}`}
|
|
339
|
+
plain
|
|
340
|
+
label={shut.includes(pr.number) ? "▸" : "▾"}
|
|
341
|
+
onPress={() => void toggle(pr)}
|
|
342
|
+
/>
|
|
343
|
+
<Text wrap="truncate-end">
|
|
344
|
+
<Link href={pr.url}>#{pr.number}</Link>
|
|
345
|
+
<Text color={STATE_COLOR[pr.state] ?? "text"}>
|
|
346
|
+
{" "}
|
|
347
|
+
{pr.state}
|
|
348
|
+
</Text>
|
|
349
|
+
<Text dimColor> [{pr.branch}]</Text> {pr.title}
|
|
363
350
|
</Text>
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
351
|
+
</Box>
|
|
352
|
+
{!shut.includes(pr.number) && (
|
|
353
|
+
<Text>
|
|
354
|
+
{" "}
|
|
355
|
+
{pr.review && (
|
|
356
|
+
<Text
|
|
357
|
+
color={pr.review === "approved" ? "success" : "warning"}
|
|
358
|
+
>
|
|
359
|
+
{pr.review}{" "}
|
|
360
|
+
</Text>
|
|
361
|
+
)}
|
|
362
|
+
<Text color={CHECKS[pr.checks].color}>
|
|
363
|
+
{CHECKS[pr.checks].text}
|
|
375
364
|
</Text>
|
|
376
|
-
|
|
377
|
-
<Text color={CHECKS[pr.checks].color}>
|
|
378
|
-
{CHECKS[pr.checks].text}
|
|
365
|
+
<Text dimColor> {pr.comments} comments</Text>
|
|
379
366
|
</Text>
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
</Box>
|
|
367
|
+
)}
|
|
368
|
+
</Box>
|
|
369
|
+
))}
|
|
370
|
+
</Box>
|
|
371
|
+
)}
|
|
386
372
|
|
|
387
|
-
|
|
388
|
-
<
|
|
389
|
-
<Text
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
{items.length === 0 && <Text dimColor>None linked yet.</Text>}
|
|
395
|
-
{items.map((item) => (
|
|
396
|
-
<Text wrap="truncate-end">
|
|
397
|
-
<Link href={item.url}>#{item.id}</Link>
|
|
398
|
-
<Text color={STATE_COLOR[item.state] ?? "text"}>
|
|
399
|
-
{" "}
|
|
400
|
-
{item.state}
|
|
401
|
-
</Text>{" "}
|
|
402
|
-
{item.title}
|
|
373
|
+
{hasWork && (
|
|
374
|
+
<Box flexDirection="column">
|
|
375
|
+
<Text>
|
|
376
|
+
<Text bold color="planMode">
|
|
377
|
+
Work items
|
|
378
|
+
</Text>
|
|
379
|
+
<Text dimColor> {items.length}</Text>
|
|
403
380
|
</Text>
|
|
404
|
-
|
|
405
|
-
|
|
381
|
+
{items.length === 0 && <Text dimColor>None linked yet.</Text>}
|
|
382
|
+
{items.map((item) => (
|
|
383
|
+
<Text wrap="truncate-end">
|
|
384
|
+
<Link href={item.url}>#{item.id}</Link>
|
|
385
|
+
<Text color={STATE_COLOR[item.state] ?? "text"}>
|
|
386
|
+
{" "}
|
|
387
|
+
{item.state}
|
|
388
|
+
</Text>{" "}
|
|
389
|
+
{item.title}
|
|
390
|
+
</Text>
|
|
391
|
+
))}
|
|
392
|
+
</Box>
|
|
393
|
+
)}
|
|
406
394
|
|
|
407
395
|
<Box flexDirection="row" columnGap={1}>
|
|
408
396
|
<Button
|
|
@@ -411,11 +399,13 @@ export const register: Register = (on) => {
|
|
|
411
399
|
hotkey="r"
|
|
412
400
|
onPress={() => void Promise.all([refreshWork($), summarize($)])}
|
|
413
401
|
/>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
402
|
+
{hasWork && (
|
|
403
|
+
<Text dimColor>
|
|
404
|
+
{current
|
|
405
|
+
? `PRs updated ${ago(current.fetchedAt)}`
|
|
406
|
+
: "PRs not fetched yet"}
|
|
407
|
+
</Text>
|
|
408
|
+
)}
|
|
419
409
|
</Box>
|
|
420
410
|
</Box>
|
|
421
411
|
)
|
|
@@ -167,9 +167,9 @@ function fakeWorld(
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
const PANE = {
|
|
170
|
-
plugin: "work-
|
|
170
|
+
plugin: "work-pane",
|
|
171
171
|
component: "Pane",
|
|
172
|
-
requestId: "work-
|
|
172
|
+
requestId: "work-pane",
|
|
173
173
|
props: {
|
|
174
174
|
title: "Work",
|
|
175
175
|
isFocused: true,
|
|
@@ -231,6 +231,23 @@ test("Refresh skips the model while the session has no messages", async ($, on)
|
|
|
231
231
|
await ui.unmount()
|
|
232
232
|
})
|
|
233
233
|
|
|
234
|
+
test("a remote that is neither GitHub nor Azure DevOps hides PRs and work items", async ($, on) => {
|
|
235
|
+
fakeWorld(on, [], [message("hello")], (argv) =>
|
|
236
|
+
argv[0] === "git" && argv[1] === "remote"
|
|
237
|
+
? "git@gitlab.com:o/repo.git\n"
|
|
238
|
+
: undefined,
|
|
239
|
+
)
|
|
240
|
+
const ui = await $.ui.mount({ ...PANE, surface: "terminal" })
|
|
241
|
+
await ui.press({ key: "refresh" })
|
|
242
|
+
expect(
|
|
243
|
+
await ui.find({ type: "Text", text: /Ship the thing\./ }),
|
|
244
|
+
).toBeDefined()
|
|
245
|
+
for (const text of [/Pull requests/, /Work items/, /neither/, /^PRs /])
|
|
246
|
+
expect(await ui.find({ type: "Text", text })).toBeUndefined()
|
|
247
|
+
expect(await ui.find({ type: "Button", label: "Refresh" })).toBeDefined()
|
|
248
|
+
await ui.unmount()
|
|
249
|
+
})
|
|
250
|
+
|
|
234
251
|
function fakeSession(on: On, start: { id: string; turns: number }) {
|
|
235
252
|
const session = { ...start }
|
|
236
253
|
on("session.id", () => ({ value: session.id }))
|
|
@@ -284,6 +301,9 @@ test("a new session never opens the pane by itself, even after its own turns", a
|
|
|
284
301
|
session.turns = 1
|
|
285
302
|
await clock.advance(10_000)
|
|
286
303
|
expect(opened).toEqual([])
|
|
304
|
+
await $.command.run({ command: "work", args: "" })
|
|
305
|
+
await clock.settle()
|
|
306
|
+
expect(opened).toEqual(["work-pane"])
|
|
287
307
|
})
|
|
288
308
|
|
|
289
309
|
test("--resume opens the pane at start and summarizes once", async ($, on) => {
|
|
@@ -293,10 +313,10 @@ test("--resume opens the pane at start and summarizes once", async ($, on) => {
|
|
|
293
313
|
fakeSession(on, { id: "a", turns: 4 })
|
|
294
314
|
await $.session.start(START)
|
|
295
315
|
await clock.settle()
|
|
296
|
-
expect(opened).toEqual(["work-
|
|
316
|
+
expect(opened).toEqual(["work-pane"])
|
|
297
317
|
expect(prompts.length).toBe(1)
|
|
298
318
|
await clock.advance(10_000)
|
|
299
|
-
expect(opened).toEqual(["work-
|
|
319
|
+
expect(opened).toEqual(["work-pane"])
|
|
300
320
|
})
|
|
301
321
|
|
|
302
322
|
test("the picker and /resume open the pane once the resumed turns load", async ($, on) => {
|
|
@@ -310,12 +330,12 @@ test("the picker and /resume open the pane once the resumed turns load", async (
|
|
|
310
330
|
session.id = "resumed"
|
|
311
331
|
session.turns = 6
|
|
312
332
|
await clock.advance(5_000)
|
|
313
|
-
expect(opened).toEqual(["work-
|
|
333
|
+
expect(opened).toEqual(["work-pane"])
|
|
314
334
|
})
|
|
315
335
|
|
|
316
336
|
test("each turn summarizes again while the pane is open, not once it closes", async ($, on) => {
|
|
317
337
|
const clock = mock.clock(on)
|
|
318
|
-
const opened = ["work-
|
|
338
|
+
const opened = ["work-pane"]
|
|
319
339
|
const prompts = fakeWorld(on, opened)
|
|
320
340
|
on("turn.complete", (_$, e) => ({ text: e.answer }))
|
|
321
341
|
const turn = {
|
|
@@ -335,7 +355,7 @@ test("each turn summarizes again while the pane is open, not once it closes", as
|
|
|
335
355
|
expect(prompts.length).toBe(2)
|
|
336
356
|
})
|
|
337
357
|
|
|
338
|
-
test("a resumed session with nothing to show still
|
|
358
|
+
test("a resumed session with nothing to show still opens the pane and summarizes each turn", async ($, on) => {
|
|
339
359
|
const clock = mock.clock(on)
|
|
340
360
|
const opened: string[] = []
|
|
341
361
|
const prompts = fakeWorld(on, opened, [message("hello")], (argv) =>
|
|
@@ -345,9 +365,7 @@ test("a resumed session with nothing to show still summarizes each turn once /wo
|
|
|
345
365
|
fakeSession(on, { id: "a", turns: 4 })
|
|
346
366
|
await $.session.start(START)
|
|
347
367
|
await clock.settle()
|
|
348
|
-
expect(opened).toEqual([])
|
|
349
|
-
await $.command.run({ command: "work", args: "" })
|
|
350
|
-
await clock.settle()
|
|
368
|
+
expect(opened).toEqual(["work-pane"])
|
|
351
369
|
const before = prompts.length
|
|
352
370
|
await $.turn.complete({
|
|
353
371
|
answer: "",
|
|
@@ -15,6 +15,7 @@ export type Work = {
|
|
|
15
15
|
items: Item[]
|
|
16
16
|
fetchedAt: number
|
|
17
17
|
error?: string
|
|
18
|
+
isUnsupported?: boolean
|
|
18
19
|
}
|
|
19
20
|
export type Step = { text: string; status: "done" | "current" | "todo" }
|
|
20
21
|
export type Summary =
|
|
@@ -23,7 +24,7 @@ export type Summary =
|
|
|
23
24
|
|
|
24
25
|
declare module "claude-code" {
|
|
25
26
|
interface PluginState {
|
|
26
|
-
"work-
|
|
27
|
+
"work-pane": {
|
|
27
28
|
branches: string[]
|
|
28
29
|
work: Work | null
|
|
29
30
|
isFetching: boolean
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Platform mapping reference
|
|
2
2
|
|
|
3
|
-
Reverse map used by the `universalize-agents` skill.
|
|
4
|
-
`src/utils/paths.ts` in this repository
|
|
3
|
+
Reverse map used by the `universalize-agents` skill. The Skills rows come from
|
|
4
|
+
`src/utils/paths.ts` in this repository; keep them in sync with it. The Agents
|
|
5
|
+
and Commands rows are maintained here only.
|
|
5
6
|
|
|
6
7
|
## Source directories (discover from / symlink to)
|
|
7
8
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kurokeita/add-skill",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "CLI to install AI agent skills to various platforms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"ai-agent": "
|
|
7
|
+
"ai-agent": "dist/bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "dist/bin/cli.js",
|
|
10
10
|
"files": [
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"author": "Kuro Keita",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/kurokeita/ai-agent.git"
|
|
34
|
+
"url": "git+https://github.com/kurokeita/ai-agent.git"
|
|
35
35
|
},
|
|
36
36
|
"license": "GPL-3.0",
|
|
37
37
|
"packageManager": "pnpm@10.28.0",
|