@simplysm/sd-claude 14.0.79 → 14.0.81
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/claude/references/sd-requirement-source-handling.md +17 -17
- package/claude/references/sd-simplysm14/README.md +58 -58
- package/claude/references/sd-simplysm14/manuals/client-component.md +739 -739
- package/claude/references/sd-simplysm14/manuals/client-crud.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-demo.md +1 -1
- package/claude/references/sd-simplysm14/manuals/client-setup.md +2 -2
- package/claude/references/sd-simplysm14/manuals/client-tab.md +2 -2
- package/claude/references/sd-simplysm14/manuals/logging.md +3 -3
- package/claude/references/sd-simplysm14/manuals/orm-union.md +7 -7
- package/claude/references/sd-simplysm14/manuals/orm.md +75 -75
- package/claude/references/sd-simplysm14/manuals/test.md +8 -8
- package/claude/rules/sd-base-rules.md +261 -354
- package/claude/rules/sd-design-rules.md +44 -0
- package/claude/{sd-check-forbidden-files.py → sd-check-edit.py} +2 -1
- package/claude/{sd-check-bash.py → sd-check-shell.py} +2 -2
- package/claude/settings.json +3 -4
- package/claude/skills/sd-commit/SKILL.md +17 -17
- package/claude/skills/sd-config/SKILL.md +4 -4
- package/claude/skills/sd-demo/SKILL.md +41 -43
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/.specs/inventory/spec.md +99 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/package.json +12 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/index.ts +3 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inbound/inbound.list.ts +150 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/inventory/inventory-master.list.ts +143 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/packages/demo-client/src/screens/outbound/outbound.list.ts +150 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/pnpm-workspace.yaml +2 -0
- package/claude/skills/sd-demo/evals/fixtures/inventory-list/sd.config.ts +12 -0
- package/claude/skills/sd-demo/evals/golden.jsonl +1 -5
- package/claude/skills/sd-dev/SKILL.md +49 -22
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/package.json +8 -0
- package/claude/skills/sd-dev/evals/fixtures/minimal-ts-pkg/tests/.gitkeep +0 -0
- package/claude/skills/sd-dev/evals/fixtures/{case-modify → minimal-ts-pkg}/tsconfig.json +1 -3
- package/claude/skills/sd-dev/evals/golden.jsonl +1 -3
- package/claude/skills/sd-docs/SKILL.md +8 -8
- package/claude/skills/sd-impl/SKILL.md +172 -82
- package/claude/skills/sd-impl/evals/fixtures/case-a-new-screen/.specs/260513120000_warehouse/spec.md +101 -0
- package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/.specs/260513120000_warehouse/spec.md +101 -0
- package/claude/skills/sd-impl/evals/fixtures/case-b-update-with-demo/packages/app/src/screens/box-register/box-register.view.ts +46 -0
- package/claude/skills/sd-impl/evals/fixtures/case-c-new-cross/.specs/260513120000_warehouse/spec.md +89 -0
- package/claude/skills/sd-impl/evals/fixtures/case-d-spec-modify/.specs/260513120000_warehouse/spec.md +101 -0
- package/claude/skills/sd-impl/evals/golden.jsonl +4 -6
- package/claude/skills/sd-review/SKILL.md +33 -0
- package/claude/skills/sd-review/evals/fixtures/code-review/src/foo.ts +7 -0
- package/claude/skills/sd-review/evals/fixtures/doc-review/docs/foo.md +4 -0
- package/claude/skills/sd-review/evals/golden.jsonl +2 -0
- package/claude/skills/sd-skill/SKILL.md +217 -29
- package/claude/skills/sd-skill/evals/fixtures/existing-skill/.claude/skills/todo-format/SKILL.md +14 -0
- package/claude/skills/sd-skill/evals/fixtures/new-skill/.gitkeep +0 -0
- package/claude/skills/sd-skill/evals/golden.jsonl +2 -5
- package/claude/skills/sd-spec/SKILL.md +384 -305
- package/claude/skills/sd-spec/references/example-spec.md +41 -64
- package/claude/skills/sd-unpack/SKILL.md +83 -83
- package/claude/skills/sd-use/SKILL.md +4 -4
- package/package.json +1 -1
- package/claude/output-styles/sd-tone.md +0 -152
- package/claude/skills/sd-demo/evals/fixtures/empty/.specs/260513120000_warehouse/spec.md +0 -45
- package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/.specs/260513120000_warehouse/spec.md +0 -42
- package/claude/skills/sd-demo/evals/fixtures/with-existing-screen/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
- package/claude/skills/sd-demo/evals/fixtures/with-master-screen/.specs/260513120000_warehouse/spec.md +0 -45
- package/claude/skills/sd-demo/evals/fixtures/with-master-screen/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
- package/claude/skills/sd-demo/evals/fixtures/with-modal/.specs/260513120000_warehouse/spec.md +0 -75
- package/claude/skills/sd-demo/evals/fixtures/with-modal/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
- package/claude/skills/sd-demo/evals/fixtures/with-screens/.specs/260513120000_warehouse/spec.md +0 -45
- package/claude/skills/sd-demo/evals/fixtures/with-screens/packages/app/src/screens/dashboard/dashboard.view.ts +0 -33
- package/claude/skills/sd-dev/evals/fixtures/case-add/package.json +0 -13
- package/claude/skills/sd-dev/evals/fixtures/case-add/src/index.ts +0 -10
- package/claude/skills/sd-dev/evals/fixtures/case-add/tests/index.test.ts +0 -11
- package/claude/skills/sd-dev/evals/fixtures/case-add/tsconfig.json +0 -12
- package/claude/skills/sd-dev/evals/fixtures/case-bug/package.json +0 -13
- package/claude/skills/sd-dev/evals/fixtures/case-bug/src/index.ts +0 -10
- package/claude/skills/sd-dev/evals/fixtures/case-bug/tests/index.test.ts +0 -11
- package/claude/skills/sd-dev/evals/fixtures/case-bug/tsconfig.json +0 -12
- package/claude/skills/sd-dev/evals/fixtures/case-modify/package.json +0 -13
- package/claude/skills/sd-dev/evals/fixtures/case-modify/src/index.ts +0 -10
- package/claude/skills/sd-dev/evals/fixtures/case-modify/tests/index.test.ts +0 -11
- package/claude/skills/sd-impl/evals/fixtures/case-001-new-screen/spec.md +0 -55
- package/claude/skills/sd-impl/evals/fixtures/case-002-auto-process/spec.md +0 -55
- package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/packages/client/src/pages/book-list.ts +0 -22
- package/claude/skills/sd-impl/evals/fixtures/case-003-update-screen/spec.md +0 -57
- package/claude/skills/sd-impl/evals/fixtures/case-004-ambiguous-spec/spec.md +0 -58
- package/claude/skills/sd-impl/evals/fixtures/case-005-id-mismatch/spec.md +0 -52
- package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.test.ts +0 -10
- package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/client/src/pages//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.ts +0 -11
- package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/data-access//352/261/260/353/236/230/354/262/230-/354/240/221/352/267/274.ts +0 -12
- package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/packages/server/src/models//352/261/260/353/236/230/354/262/230.ts +0 -8
- package/claude/skills/sd-impl/evals/fixtures/case-006-with-reference-units/spec.md +0 -77
- package/claude/skills/sd-impl/evals/fixtures/case-new/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +0 -101
- package/claude/skills/sd-impl/evals/fixtures/case-update/.specs/260514120000_/352/261/260/353/236/230/354/262/230/spec.md +0 -101
- package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/250/353/215/270.txt +0 -1
- package/claude/skills/sd-impl/evals/fixtures/case-update/src//352/261/260/353/236/230/354/262/230//352/261/260/353/236/230/354/262/230-/353/252/251/353/241/235.txt +0 -1
- package/claude/skills/sd-impl/references/spec-cross-check.md +0 -82
- package/claude/skills/sd-skill/evals/fixtures/with-existing-review/.claude/skills/review/SKILL.md +0 -14
- package/claude/skills/sd-skill/references/eval-authoring.md +0 -81
- package/claude/skills/sd-skill/references/eval-run.md +0 -32
- package/claude/skills/sd-skill/references/skill-authoring.md +0 -70
- /package/claude/skills/{sd-skill/evals/fixtures/empty → sd-dev/evals/fixtures/minimal-ts-pkg/src}/.gitkeep +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
ViewEncapsulation,
|
|
5
|
+
effect,
|
|
6
|
+
inject,
|
|
7
|
+
signal,
|
|
8
|
+
untracked,
|
|
9
|
+
} from "@angular/core";
|
|
10
|
+
import {
|
|
11
|
+
injectPermsSignal,
|
|
12
|
+
mark,
|
|
13
|
+
SdCrudListComponent,
|
|
14
|
+
SdSheetColumnDirective,
|
|
15
|
+
SdTextfieldComponent,
|
|
16
|
+
SdToastProvider,
|
|
17
|
+
} from "@simplysm/angular";
|
|
18
|
+
|
|
19
|
+
interface IInventoryMasterItem {
|
|
20
|
+
id: number;
|
|
21
|
+
warehouseCode: string;
|
|
22
|
+
itemCode: string;
|
|
23
|
+
itemName: string;
|
|
24
|
+
active: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface IFilter {
|
|
28
|
+
searchText: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Component({
|
|
32
|
+
selector: "app-inventory-master-list",
|
|
33
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
34
|
+
encapsulation: ViewEncapsulation.None,
|
|
35
|
+
standalone: true,
|
|
36
|
+
imports: [SdCrudListComponent, SdSheetColumnDirective, SdTextfieldComponent],
|
|
37
|
+
template: `
|
|
38
|
+
<div class="flex-column fill">
|
|
39
|
+
<sd-crud-list
|
|
40
|
+
title="재고 마스터"
|
|
41
|
+
[(ready)]="ready"
|
|
42
|
+
[initialized]="initialized()"
|
|
43
|
+
[(busyCount)]="busyCount"
|
|
44
|
+
[items]="items()"
|
|
45
|
+
[(selectedKeys)]="selectedKeys"
|
|
46
|
+
[(page)]="page"
|
|
47
|
+
[totalPageCount]="pageLength()"
|
|
48
|
+
[(sorts)]="sortingDefs"
|
|
49
|
+
[trackByFn]="trackByFn"
|
|
50
|
+
[restricted]="!perms().includes('use')"
|
|
51
|
+
(filterSubmit)="onFilterSubmit()"
|
|
52
|
+
>
|
|
53
|
+
<ng-template #filterTpl>
|
|
54
|
+
<div class="form-box-inline">
|
|
55
|
+
<div>
|
|
56
|
+
<label>검색</label>
|
|
57
|
+
<sd-textfield [(value)]="filter().searchText" (valueChange)="mark(filter)" />
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</ng-template>
|
|
61
|
+
|
|
62
|
+
<sd-sheet-column [key]="'warehouseCode'" [header]="'창고'">
|
|
63
|
+
<ng-template [cell]="items()" let-item="item">
|
|
64
|
+
<div class="p-xs-sm">{{ item.warehouseCode }}</div>
|
|
65
|
+
</ng-template>
|
|
66
|
+
</sd-sheet-column>
|
|
67
|
+
|
|
68
|
+
<sd-sheet-column [key]="'itemCode'" [header]="'품목 코드'">
|
|
69
|
+
<ng-template [cell]="items()" let-item="item">
|
|
70
|
+
<div class="p-xs-sm">{{ item.itemCode }}</div>
|
|
71
|
+
</ng-template>
|
|
72
|
+
</sd-sheet-column>
|
|
73
|
+
|
|
74
|
+
<sd-sheet-column [key]="'itemName'" [header]="'품목명'">
|
|
75
|
+
<ng-template [cell]="items()" let-item="item">
|
|
76
|
+
<div class="p-xs-sm">{{ item.itemName }}</div>
|
|
77
|
+
</ng-template>
|
|
78
|
+
</sd-sheet-column>
|
|
79
|
+
</sd-crud-list>
|
|
80
|
+
|
|
81
|
+
@if (initialized() && items().length === 0) {
|
|
82
|
+
<div class="p-default tx-center tx-theme-gray-default">조회된 재고 마스터가 없습니다.</div>
|
|
83
|
+
}
|
|
84
|
+
</div>
|
|
85
|
+
`,
|
|
86
|
+
})
|
|
87
|
+
export class InventoryMasterListComponent {
|
|
88
|
+
private readonly _sdToast = inject(SdToastProvider);
|
|
89
|
+
|
|
90
|
+
perms = injectPermsSignal(["inventory.master"], ["use", "edit"]);
|
|
91
|
+
|
|
92
|
+
ready = signal(false);
|
|
93
|
+
initialized = signal(false);
|
|
94
|
+
busyCount = signal(0);
|
|
95
|
+
|
|
96
|
+
items = signal<IInventoryMasterItem[]>([]);
|
|
97
|
+
selectedKeys = signal<number[]>([]);
|
|
98
|
+
page = signal(0);
|
|
99
|
+
pageLength = signal(0);
|
|
100
|
+
sortingDefs = signal<{ key: string; desc: boolean }[]>([]);
|
|
101
|
+
|
|
102
|
+
filter = signal<IFilter>({ searchText: "" });
|
|
103
|
+
lastFilter = signal<IFilter>({ searchText: "" });
|
|
104
|
+
|
|
105
|
+
trackByFn = (item: IInventoryMasterItem) => item.id;
|
|
106
|
+
|
|
107
|
+
protected readonly mark = mark;
|
|
108
|
+
|
|
109
|
+
constructor() {
|
|
110
|
+
effect(() => {
|
|
111
|
+
if (!this.perms().includes("use") || !this.ready()) {
|
|
112
|
+
this.initialized.set(true);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.lastFilter();
|
|
117
|
+
this.page();
|
|
118
|
+
this.sortingDefs();
|
|
119
|
+
|
|
120
|
+
void untracked(async () => {
|
|
121
|
+
this.busyCount.update((v) => v + 1);
|
|
122
|
+
await this._sdToast.try(async () => {
|
|
123
|
+
await this._refresh();
|
|
124
|
+
});
|
|
125
|
+
this.busyCount.update((v) => v - 1);
|
|
126
|
+
this.initialized.set(true);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
onFilterSubmit(): void {
|
|
132
|
+
this.page.set(0);
|
|
133
|
+
this.lastFilter.set({ ...this.filter() });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
doRefresh(): void {
|
|
137
|
+
if (!this.perms().includes("use")) return;
|
|
138
|
+
mark(this.lastFilter);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async _refresh(): Promise<void> {
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
ViewEncapsulation,
|
|
5
|
+
effect,
|
|
6
|
+
inject,
|
|
7
|
+
signal,
|
|
8
|
+
untracked,
|
|
9
|
+
} from "@angular/core";
|
|
10
|
+
import {
|
|
11
|
+
injectPermsSignal,
|
|
12
|
+
mark,
|
|
13
|
+
SdCrudListComponent,
|
|
14
|
+
SdSheetColumnDirective,
|
|
15
|
+
SdTextfieldComponent,
|
|
16
|
+
SdToastProvider,
|
|
17
|
+
} from "@simplysm/angular";
|
|
18
|
+
|
|
19
|
+
interface IOutboundItem {
|
|
20
|
+
id: number;
|
|
21
|
+
orderNo: string;
|
|
22
|
+
customerName: string;
|
|
23
|
+
itemName: string;
|
|
24
|
+
quantity: number;
|
|
25
|
+
shippedAt: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface IFilter {
|
|
29
|
+
searchText: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Component({
|
|
33
|
+
selector: "app-outbound-list",
|
|
34
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
35
|
+
encapsulation: ViewEncapsulation.None,
|
|
36
|
+
standalone: true,
|
|
37
|
+
imports: [SdCrudListComponent, SdSheetColumnDirective, SdTextfieldComponent],
|
|
38
|
+
template: `
|
|
39
|
+
<div class="flex-column fill">
|
|
40
|
+
<sd-crud-list
|
|
41
|
+
title="출고 내역 조회"
|
|
42
|
+
[(ready)]="ready"
|
|
43
|
+
[initialized]="initialized()"
|
|
44
|
+
[(busyCount)]="busyCount"
|
|
45
|
+
[items]="items()"
|
|
46
|
+
[(selectedKeys)]="selectedKeys"
|
|
47
|
+
[(page)]="page"
|
|
48
|
+
[totalPageCount]="pageLength()"
|
|
49
|
+
[(sorts)]="sortingDefs"
|
|
50
|
+
[trackByFn]="trackByFn"
|
|
51
|
+
[restricted]="!perms().includes('use')"
|
|
52
|
+
(filterSubmit)="onFilterSubmit()"
|
|
53
|
+
>
|
|
54
|
+
<ng-template #filterTpl>
|
|
55
|
+
<div class="form-box-inline">
|
|
56
|
+
<div>
|
|
57
|
+
<label>검색</label>
|
|
58
|
+
<sd-textfield [(value)]="filter().searchText" (valueChange)="mark(filter)" />
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</ng-template>
|
|
62
|
+
|
|
63
|
+
<sd-sheet-column [key]="'orderNo'" [header]="'출고 번호'">
|
|
64
|
+
<ng-template [cell]="items()" let-item="item">
|
|
65
|
+
<div class="p-xs-sm">{{ item.orderNo }}</div>
|
|
66
|
+
</ng-template>
|
|
67
|
+
</sd-sheet-column>
|
|
68
|
+
|
|
69
|
+
<sd-sheet-column [key]="'customerName'" [header]="'거래처'">
|
|
70
|
+
<ng-template [cell]="items()" let-item="item">
|
|
71
|
+
<div class="p-xs-sm">{{ item.customerName }}</div>
|
|
72
|
+
</ng-template>
|
|
73
|
+
</sd-sheet-column>
|
|
74
|
+
|
|
75
|
+
<sd-sheet-column [key]="'itemName'" [header]="'품목'">
|
|
76
|
+
<ng-template [cell]="items()" let-item="item">
|
|
77
|
+
<div class="p-xs-sm">{{ item.itemName }}</div>
|
|
78
|
+
</ng-template>
|
|
79
|
+
</sd-sheet-column>
|
|
80
|
+
|
|
81
|
+
<sd-sheet-column [key]="'quantity'" [header]="'수량'">
|
|
82
|
+
<ng-template [cell]="items()" let-item="item">
|
|
83
|
+
<div class="p-xs-sm tx-right">{{ item.quantity }}</div>
|
|
84
|
+
</ng-template>
|
|
85
|
+
</sd-sheet-column>
|
|
86
|
+
</sd-crud-list>
|
|
87
|
+
|
|
88
|
+
@if (initialized() && items().length === 0) {
|
|
89
|
+
<div class="p-default tx-center tx-theme-gray-default">조회된 출고 내역이 없습니다.</div>
|
|
90
|
+
}
|
|
91
|
+
</div>
|
|
92
|
+
`,
|
|
93
|
+
})
|
|
94
|
+
export class OutboundListComponent {
|
|
95
|
+
private readonly _sdToast = inject(SdToastProvider);
|
|
96
|
+
|
|
97
|
+
perms = injectPermsSignal(["outbound"], ["use"]);
|
|
98
|
+
|
|
99
|
+
ready = signal(false);
|
|
100
|
+
initialized = signal(false);
|
|
101
|
+
busyCount = signal(0);
|
|
102
|
+
|
|
103
|
+
items = signal<IOutboundItem[]>([]);
|
|
104
|
+
selectedKeys = signal<number[]>([]);
|
|
105
|
+
page = signal(0);
|
|
106
|
+
pageLength = signal(0);
|
|
107
|
+
sortingDefs = signal<{ key: string; desc: boolean }[]>([]);
|
|
108
|
+
|
|
109
|
+
filter = signal<IFilter>({ searchText: "" });
|
|
110
|
+
lastFilter = signal<IFilter>({ searchText: "" });
|
|
111
|
+
|
|
112
|
+
trackByFn = (item: IOutboundItem) => item.id;
|
|
113
|
+
|
|
114
|
+
protected readonly mark = mark;
|
|
115
|
+
|
|
116
|
+
constructor() {
|
|
117
|
+
effect(() => {
|
|
118
|
+
if (!this.perms().includes("use") || !this.ready()) {
|
|
119
|
+
this.initialized.set(true);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.lastFilter();
|
|
124
|
+
this.page();
|
|
125
|
+
this.sortingDefs();
|
|
126
|
+
|
|
127
|
+
void untracked(async () => {
|
|
128
|
+
this.busyCount.update((v) => v + 1);
|
|
129
|
+
await this._sdToast.try(async () => {
|
|
130
|
+
await this._refresh();
|
|
131
|
+
});
|
|
132
|
+
this.busyCount.update((v) => v - 1);
|
|
133
|
+
this.initialized.set(true);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
onFilterSubmit(): void {
|
|
139
|
+
this.page.set(0);
|
|
140
|
+
this.lastFilter.set({ ...this.filter() });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
doRefresh(): void {
|
|
144
|
+
if (!this.perms().includes("use")) return;
|
|
145
|
+
mark(this.lastFilter);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private async _refresh(): Promise<void> {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
{"id": "
|
|
2
|
-
{"id": "modal-screen", "input": "/sd-demo .specs/260513120000_warehouse/spec.md 의 §4.1 화면을 데모로 만들어줘", "rubric": ["packages/app/src/screens/ 아래에 새 .ts 파일이 2개 이상 생성되었는가? (호출 화면 + 모달 화면, dashboard/ 하위 제외)", "새로 생성된 파일 중 모달 역할 파일이 권위 규약의 '.modal.ts' 접미사를 사용하는가?", "새로 생성된 파일 중 적어도 하나에 'SdModalProvider' 식별자가 포함되었는가?", "새로 생성된 파일 중 적어도 하나에 '_sdModal.showAsync(' 호출 코드가 포함되었는가?", "새로 생성된 파일 중 적어도 하나에 'close' 라는 이름의 output 선언이 포함되었는가?", "기존 packages/app/src/screens/dashboard/dashboard.view.ts 파일이 손실되지 않고 보존되었는가?"], "fixture": "with-modal"}
|
|
3
|
-
{"id": "recall-overwrite", "input": "/sd-demo .specs/260513120000_warehouse/spec.md 의 §4.1 화면을 데모로 만들어줘. 이미 파일이 있으면 ① 덮어쓰기 분기로 진행해줘.", "rubric": ["packages/app/src/screens/dashboard/ 디렉토리 안의 화면 파일이 spec §4.1 의 'Total stock' 또는 'Refresh' 중 하나의 문자열을 포함하는가?", "packages/app/src/screens/dashboard/ 디렉토리 안의 화면 파일에 'standalone: true' 가 포함되었는가?", "packages/app/src/screens/dashboard/ 디렉토리 안의 화면 파일에 '// sd-demo:' 로 시작하는 주석이 1개 이상 있는가?"], "fixture": "with-existing-screen"}
|
|
4
|
-
{"id": "empty-screen", "input": "/sd-demo .specs/260513120000_warehouse/spec.md 의 §4.1 화면을 데모로 만들어줘", "rubric": ["fixture 안 어딘가에 .ts 파일이 새로 1개 이상 생성되었는가? (.specs/, 메타 파일 제외)", "새로 생성된 파일의 파일명이 권위 규약(<domain>.list.ts / .detail.ts / .view.ts / .modal.ts / .ts) 중 하나의 형식을 따르는가? (.component.ts 형식이면 FAIL)", "새로 생성된 파일 중 적어도 하나의 @Component selector 가 'app-' prefix 로 시작하는가?", "새로 생성된 파일 중 적어도 하나에 'standalone: true' 가 포함되었는가?", "새로 생성된 파일 중 적어도 하나에 'sd-textfield' 또는 '<input' 중 하나가 1개 이상 포함되었는가?", "새로 생성된 파일 중 적어도 하나에 '// sd-demo:' 로 시작하는 주석이 1개 이상 있는가?"], "fixture": "empty"}
|
|
5
|
-
{"id": "master-screen", "input": "/sd-demo .specs/260513120000_warehouse/spec.md 의 §4.1 화면을 데모로 만들어줘", "rubric": ["packages/app/src/screens/ 아래에 새 .ts 파일이 1개 이상 생성되었는가? (dashboard/ 하위 제외)", "새로 생성된 파일의 파일명이 권위 규약의 '.list.ts' 접미사를 사용하는가? (마스터 화면은 sd-crud-list 채택이 표준이며 .list.ts 가 권위 규약)", "새로 생성된 .ts 파일 중 적어도 하나의 템플릿에 'sd-crud-list' selector 가 1개 이상 포함되었는가?", "새로 생성된 .ts 파일 중 적어도 하나에 '// sd-demo:' 로 시작하는 주석이 1개 이상 있는가?"], "fixture": "with-master-screen"}
|
|
1
|
+
{"id": "case-001", "input": "/sd-demo .specs/inventory/spec.md §4.1 데모 만들어줘", "rubric": ["fixture 의 `packages/demo-client/src/screens/inventory/` 폴더 안에 화면 컴포넌트 파일이 새로 생성되었는가", "생성된 컴포넌트 파일이 Angular @Component 데코레이터 + selector 를 가지는가", "생성된 컴포넌트의 template 에 필터 영역·시트 영역·빈 상태 영역 마크업이 모두 등장하는가", "생성된 컴포넌트의 template 가 답습 화면(출고·입고 조회) 의 부위 마크업 구조(같은 컴포넌트·같은 클래스 패턴 사용)와 일치하는가", "생성된 파일 본문에 `// sd-demo:` 마커가 1회 이상 등장하는가", "events 에 `.claude/references/sd-simplysm14/` 폴더 안 파일 Read 또는 동등 명령 1회 이상 있는가"], "fixture": "inventory-list"}
|
|
@@ -1,44 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-dev
|
|
3
|
-
description: 코드 변경 요청을
|
|
3
|
+
description: 코드 변경 요청을 사용자와 합의 후 코드 변경분과 테스트로 산출. Use when 화면 단위 spec 분석이 필요 없는 라이브러리·CLI·내부 모듈의 기능 추가·수정·버그 수정 요청 시.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# sd-dev
|
|
7
7
|
|
|
8
|
-
spec.md 없이 진행하는 가벼운 코드 작업. 의도
|
|
8
|
+
spec.md 없이 진행하는 가벼운 코드 작업. 의도 합의 후 워크플로는 자동 진행 — 단 파일 삭제·시연 등 확인성 보고는 단계별 발생. 합의 결과는 대화 메모리에만.
|
|
9
9
|
|
|
10
10
|
## 워크플로
|
|
11
11
|
|
|
12
12
|
### 1단계: 의도파악
|
|
13
13
|
|
|
14
|
-
사용자 발화를 토대로 무엇을 만들거나 바꿀지 합의.
|
|
14
|
+
사용자 발화를 토대로 무엇을 만들거나 바꿀지 합의. 다음을 확정해야 진행:
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- 작업 종류: 신규 추가 / 기존 수정 / 버그 수정.
|
|
17
|
+
- 대상 파일·모듈·패키지.
|
|
18
|
+
- 변경의 입출력·동작 — 이름·시그니처·예외 동작 등.
|
|
17
19
|
|
|
18
|
-
-
|
|
19
|
-
- 대상 파일·모듈·패키지
|
|
20
|
-
- 변경의 입출력·동작 — 이름·시그니처·예외 동작 등
|
|
21
|
-
|
|
22
|
-
근거 충분(사용자 발화에 명시 + 기존 코드 패턴 추론 가능)이면 묻지 않고 진행. 외부 자료(시크릿·시안·샘플 데이터)가 필요하면 이 단계에서 요청.
|
|
20
|
+
근거 충분(사용자 발화 명시 + 기존 코드 패턴 추론 가능)이면 묻지 않고 진행. 부족분은 1건씩 질문 (sd-base-rules "사용자 질의 시"). 외부 자료(시크릿·시안·샘플 데이터)가 필요하면 이 단계에서 요청.
|
|
23
21
|
|
|
24
22
|
### 2단계: 분석
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
부재로 워크플로를 멈추지 않음. 발견된 만큼 활용.
|
|
25
|
+
|
|
26
|
+
**A. 라이브러리·개발 매뉴얼**:
|
|
27
|
+
- `@simplysm/*` 14.x — `.claude/references/sd-simplysm14/README.md` 참조.
|
|
28
|
+
- 그 외 framework — 코드베이스 안 동등 위치 문서.
|
|
29
|
+
- 없으면 표준 패턴.
|
|
30
|
+
|
|
31
|
+
**B. 기존 패턴**:
|
|
32
|
+
- 작업 영역 인접 코드의 파일 위치·네이밍·구조·계층 분리 패턴 파악.
|
|
33
|
+
- 동일 의도 기존 사용처 1~2개 Read.
|
|
34
|
+
|
|
35
|
+
**C. 테스트 환경**:
|
|
36
|
+
- 단위 테스트 프로젝트 구분·실행 명령·mocking 패턴 파악.
|
|
37
|
+
|
|
38
|
+
### 3단계: 작업 분해 표
|
|
39
|
+
|
|
40
|
+
2단계 분석을 토대로 작업 분해 표 작성. assistant 응답으로 출력 (4단계 입력).
|
|
27
41
|
|
|
28
|
-
|
|
42
|
+
| 항목 | 요구 | 현재 코드 상태 | 판정 | 매핑 파일 | 의존 |
|
|
43
|
+
| ---- | ---- | -------------- | ---- | --------- | ---- |
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
**항목 분해 단위**:
|
|
46
|
+
- 함수·메서드 1개당 1줄.
|
|
47
|
+
- 상태값·분기 케이스 1개당 1줄.
|
|
48
|
+
- 입출력 시그니처 1개당 1줄.
|
|
49
|
+
- 버그 1건당 1줄.
|
|
50
|
+
|
|
51
|
+
**컬럼**:
|
|
52
|
+
- **항목**: 분해 단위 1개의 짧은 식별자.
|
|
53
|
+
- **요구**: 1단계 의도파악 합의 내용 인용.
|
|
54
|
+
- **현재 코드 상태**: 코드베이스 조사 결과. 신규는 "없음", 수정은 "있음(어떻게)".
|
|
55
|
+
- **판정**: 없음 / 불일치 / 일치.
|
|
56
|
+
- **매핑 파일**: 작성·갱신될 파일 경로.
|
|
57
|
+
- **의존**: 다른 항목 ID.
|
|
31
58
|
|
|
32
59
|
### 4단계: TDD 사이클
|
|
33
60
|
|
|
34
|
-
|
|
61
|
+
표의 (없음·불일치) 항목만 의존 순서로 진행. 일치 항목은 손대지 않음.
|
|
62
|
+
|
|
63
|
+
각 작업(= 표 1행) 시작 시 **테스트 작성 가능 여부** 판정 — 입출력 명확 + 외부 의존 통제 가능한가.
|
|
35
64
|
|
|
36
|
-
- **테스트 가능**: **RED → GREEN → REFACTOR
|
|
37
|
-
- **RED**: 테스트만 작성 →
|
|
38
|
-
- **GREEN**: 통과하는 최소 구현 →
|
|
65
|
+
- **테스트 가능**: **RED → GREEN → REFACTOR**.
|
|
66
|
+
- **RED**: 테스트만 작성 → 단위 테스트 실행 → 실패 확인. **이 단계에서 구현 파일 절대 손대지 말 것.**
|
|
67
|
+
- **GREEN**: 통과하는 최소 구현 → 단위 테스트 재실행 → 통과 확인.
|
|
39
68
|
- **REFACTOR**: 중복·가독성·기존 패턴 정합 정리 → 통과 유지 확인. 정리할 게 없으면 스킵.
|
|
40
69
|
- **테스트 불가/비효율** (UI 시각·외부 서비스 실호출 등): **구현 → REFACTOR**.
|
|
41
70
|
|
|
71
|
+
**의도 모호 발견 시**: 사이클 중 1단계에서 합의되지 않은 모호함 발견 → 즉시 멈추고 1단계 회귀. 자체 판단 채움 금지.
|
|
72
|
+
|
|
42
73
|
### 5단계: 코드 정리
|
|
43
74
|
|
|
44
75
|
전체 변경분을 한번 훑어 정돈. 4단계 REFACTOR 가 잡지 못한 횡단 이슈와 작업 잔재가 대상.
|
|
@@ -46,14 +77,10 @@ spec.md 없이 진행하는 가벼운 코드 작업. 의도 합의가 끝나면
|
|
|
46
77
|
- **횡단 중복**: 작업 사이클 사이에 동일 로직이 흩어져 있으면 합치기.
|
|
47
78
|
- **인접 코드 패턴 정합**: 코드베이스 컨벤션 vs 실제 작성 — 파일 위치·네이밍·구조.
|
|
48
79
|
- **불필요한 코드**: 미사용 import·변수·주석, 요구 없는 옵션·추상화 제거. 갱신·덮어쓰기 결과로 어디서도 참조되지 않는 파일도 포함. **단 파일 단위 삭제는 후보 목록을 사용자에게 보고 → 확정분만 삭제** (dynamic import·문서 자산 등 보존분 사용자 제외).
|
|
49
|
-
-
|
|
80
|
+
- **권위 자료 정합**: 2-A 매뉴얼 위반 항목 수정.
|
|
50
81
|
|
|
51
82
|
정리 후 단위 테스트 재실행 — 회귀 없음 확인.
|
|
52
83
|
|
|
53
84
|
### 6단계: 검증
|
|
54
85
|
|
|
55
|
-
산출물이 브라우저 시연이 필요한 화면·UI 면 사용자에게 dev 서버 실행 요청 →
|
|
56
|
-
|
|
57
|
-
## 운용
|
|
58
|
-
|
|
59
|
-
- 결정 근거: `sd-base-rules.md` "결정 근거" 적용.
|
|
86
|
+
산출물이 브라우저 시연이 필요한 화면·UI 면 사용자에게 dev 서버 실행 요청 → 브라우저 자동화 도구로 시연. 그 외(라이브러리·CLI·내부 모듈·서버 함수)는 4단계 단위 테스트 통과로 종결.
|
|
File without changes
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
{"id": "
|
|
2
|
-
{"id": "case-modify", "input": "/sd-dev toCamelCase 가 공백도 구분자로 처리하게 바꿔줘", "fixture": "case-modify", "rubric": ["src/index.ts 의 toCamelCase 가 공백 문자를 구분자로 인식하도록 변경되었는가? (split 정규식에 공백 포함 또는 동등 처리)", "tests 디렉토리에 공백 구분자 입력 케이스 테스트가 1건 이상 추가되었는가?", "기존 kebab-case 및 snake_case 테스트 케이스가 삭제되지 않고 보존되어 있는가?", "vitest run 명령이 Bash 도구로 1회 이상 호출되었고 최종 호출의 종료 코드가 0 인가?"]}
|
|
3
|
-
{"id": "case-bug", "input": "/sd-dev toCamelCase 빈 문자열 입력하면 에러나, 고쳐줘", "fixture": "case-bug", "rubric": ["tests 디렉토리에 빈 문자열 입력 케이스 테스트가 1건 이상 추가되었는가?", "src/index.ts 의 toCamelCase 가 빈 문자열 입력 시 throw 하지 않고 빈 문자열을 반환하도록 수정되었는가?", "최종 vitest run 의 종료 코드가 0 이고 기존 테스트와 신규 빈 문자열 테스트가 모두 통과하는가?"]}
|
|
1
|
+
{"id": "sum-add", "input": "/sd-dev sum 함수 추가해줘. a + b 반환.", "rubric": ["tree.json 에 sum 함수 구현 파일이 src/ 하위 (위치 자유) 에 존재하는가", "tree.json 에 sum 함수 테스트 파일 (위치 자유) 이 존재하는가", "events 에 테스트 러너 실행 흔적 (Bash 의 node --test 또는 동등 명령) 이 1회 이상 있는가", "구현 파일 내용에 sum 함수 정의 및 export 가 포함되는가", "테스트 파일 내용에 sum 호출 + 결과 검증 assertion 이 1개 이상 있는가"], "fixture": "minimal-ts-pkg"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sd-docs
|
|
3
|
-
description: `@simplysm/*` 라이브러리 패키지의 API 문서를 `.claude/references/sd-simplysm14/apis/<패키지명>/` 자리에 사용 트리거 기준으로
|
|
3
|
+
description: `@simplysm/*` 라이브러리 패키지의 API 문서를 `.claude/references/sd-simplysm14/apis/<패키지명>/` 자리에 사용 트리거 기준으로 산출·갱신. Use when 라이브러리 API 문서를 새로 작성하거나 코드 변경을 반영해 갱신할 때.
|
|
4
4
|
effort: "low"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# sd-docs
|
|
8
8
|
|
|
9
|
-
`@simplysm/*` 라이브러리 패키지의 API 문서를 코드 진실에 맞춰
|
|
9
|
+
`@simplysm/*` 라이브러리 패키지의 API 문서를 코드 진실에 맞춰 산출·갱신함. 메인 에이전트가 패키지 목록 추출과 상위 README 인덱스 갱신을 담당하고, 패키지별 산출은 subagent 1개씩 병렬 위임함.
|
|
10
10
|
|
|
11
11
|
## 산출 자리
|
|
12
12
|
|
|
@@ -18,14 +18,14 @@ effort: "low"
|
|
|
18
18
|
|
|
19
19
|
### 1. 패키지 목록 추출
|
|
20
20
|
|
|
21
|
-
워크스페이스 루트의 `packages/*/package.json` 을 모두 읽어 다음 두 리스트를
|
|
21
|
+
워크스페이스 루트의 `packages/*/package.json` 을 모두 읽어 다음 두 리스트를 만듦.
|
|
22
22
|
|
|
23
23
|
- **public 리스트**: `private: true` 가 아닌 패키지. 각 항목 = `{ name, dir }`.
|
|
24
24
|
- **private 리스트**: `private: true` 인 패키지. 인덱스에서 제외하기 위해 보관.
|
|
25
25
|
|
|
26
26
|
### 2. 패키지별 subagent 병렬 호출
|
|
27
27
|
|
|
28
|
-
`public 리스트` 의 패키지 수만큼 `general-purpose` subagent 호출을 **단일 메시지 안에서 병렬**로
|
|
28
|
+
`public 리스트` 의 패키지 수만큼 `general-purpose` subagent 호출을 **단일 메시지 안에서 병렬**로 보냄. 각 호출 프롬프트는 [references/subagent-prompt.md](references/subagent-prompt.md) 의 양식을 그대로 사용하고, `<PACKAGE_NAME>` 과 `<PACKAGE_DIR>` 만 치환함.
|
|
29
29
|
|
|
30
30
|
각 subagent 의 산출 (풀 재작성 모드 — 기존 파일 참고 없이 처음부터 작성):
|
|
31
31
|
|
|
@@ -33,24 +33,24 @@ effort: "low"
|
|
|
33
33
|
- 필요 시 `apis/<패키지명>/<군명>.md` 재작성. 코드에서 사라진 군의 파일은 삭제.
|
|
34
34
|
- 결과 보고 1단락 (산출 파일 목록, 분할 발생 여부, 한 줄 트리거 요약).
|
|
35
35
|
|
|
36
|
-
**범위 한정**: subagent 는 `apis/<패키지명>/` 자리만
|
|
36
|
+
**범위 한정**: subagent 는 `apis/<패키지명>/` 자리만 다룸. 상위 `.claude/references/sd-simplysm14/README.md` 는 건드리지 않음 (메인 에이전트가 §3 에서 처리).
|
|
37
37
|
|
|
38
38
|
### 3. 상위 README 의 "패키지 인덱스" 섹션 갱신 (파일 보존 + 섹션 내 항목만 갱신)
|
|
39
39
|
|
|
40
|
-
`.claude/references/sd-simplysm14/README.md` 는 **풀 재작성 대상 아님**. 파일 본문·다른 섹션은 그대로 보존, "패키지 인덱스" 섹션의 항목 리스트만
|
|
40
|
+
`.claude/references/sd-simplysm14/README.md` 는 **풀 재작성 대상 아님**. 파일 본문·다른 섹션은 그대로 보존, "패키지 인덱스" 섹션의 항목 리스트만 재구성함.
|
|
41
41
|
|
|
42
42
|
모든 subagent 완료 후:
|
|
43
43
|
|
|
44
44
|
- **갱신 대상**: "패키지 인덱스" 섹션 본문(항목 리스트)만.
|
|
45
45
|
- **건드리지 않음**: 섹션 머리(`## 패키지 인덱스`), 다른 모든 섹션, 파일 상단/하단 텍스트.
|
|
46
|
-
- **항목 형식**: `- **<패키지명>** — <한 줄 트리거 요약>. 자세히: [apis/<패키지명>/README.md](./apis/<패키지명>/README.md)
|
|
46
|
+
- **항목 형식**: `- **<패키지명>** — <한 줄 트리거 요약>. 자세히: [apis/<패키지명>/README.md](./apis/<패키지명>/README.md)`.
|
|
47
47
|
- **순서**: 패키지명 알파벳순.
|
|
48
48
|
- **포함**: `public 리스트` 만.
|
|
49
49
|
- **제외**: `private 리스트` 의 패키지, 코드베이스에 더 이상 존재하지 않는 패키지.
|
|
50
50
|
|
|
51
51
|
### 4. 사용자 보고
|
|
52
52
|
|
|
53
|
-
다음 항목을 짧게 정리해
|
|
53
|
+
다음 항목을 짧게 정리해 출력함.
|
|
54
54
|
|
|
55
55
|
- 재작성된 패키지 목록 (= `public 리스트` 전체. 풀 재작성 모드 — 매번 모든 패키지 산출).
|
|
56
56
|
- 분할 발생(`<군명>.md` 가 생긴) 패키지 목록.
|