gitifact 0.2.0 → 0.3.0

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.
Files changed (30) hide show
  1. package/README.md +9 -6
  2. package/dist/browser/assets/{about-NfIJSqpC.js → about-Dbyd48t6.js} +1 -1
  3. package/dist/browser/assets/{contributors._email-B6w1SA-1.js → contributors._email-BMqQlPdF.js} +1 -1
  4. package/dist/browser/assets/{contributors.index-Dkv636DW.js → contributors.index-Dk42HR-l.js} +1 -1
  5. package/dist/browser/assets/{features._featureId-B4Ba6Tbc.js → features._featureId-zHnvA0Go.js} +1 -1
  6. package/dist/browser/assets/{requirements-Db8psmjT.js → features.index-xgyvTm5d.js} +1 -1
  7. package/dist/browser/assets/git-D8SQ9LAI.js +1 -0
  8. package/dist/browser/assets/guides._documentId-jvtVZl4b.js +1 -0
  9. package/dist/browser/assets/guides.index-DKNn9kCJ.js +1 -0
  10. package/dist/browser/assets/{index-DMRG08Xu.js → index-Cul6rpdA.js} +4 -4
  11. package/dist/browser/assets/{page-header-it9YqWBS.js → page-header-pnZFm0-7.js} +1 -1
  12. package/dist/browser/assets/product-B_C25r7E.js +75 -0
  13. package/dist/browser/assets/product-DIl1IXZo.css +1 -0
  14. package/dist/browser/assets/product.index-IBLtgiMT.js +1 -0
  15. package/dist/browser/assets/{request-state-s3JHTg5D.js → request-state-q7VzEh1O.js} +2 -2
  16. package/dist/browser/assets/requirements-BmW8BEdu.js +1 -0
  17. package/dist/browser/assets/{routes-HW2hx-iw.js → routes-BDsb61_V.js} +1 -1
  18. package/dist/browser/index.html +5 -5
  19. package/dist/docs/commit.md +36 -0
  20. package/dist/docs/design.md +42 -0
  21. package/dist/docs/product.md +21 -0
  22. package/dist/docs/spec.md +54 -0
  23. package/dist/docs/workflow.md +42 -0
  24. package/dist/main.js +875 -466
  25. package/package.json +1 -1
  26. package/dist/browser/assets/features.index-Cfxr24mB.js +0 -1
  27. package/dist/browser/assets/git-D5knlkQy.js +0 -1
  28. package/dist/browser/assets/product-Cn69vcBM.css +0 -1
  29. package/dist/browser/assets/product-DAbLI-2U.js +0 -75
  30. package/dist/skills/gitifact-workflow/SKILL.md +0 -157
package/README.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # Gitifact CLI
2
2
 
3
- > Current release: `gitifact@0.2.0` (unscoped). Requires Node.js 24.x and Git.
3
+ > Current release: `gitifact@0.3.0` (unscoped). Requires Node.js 24.x and Git.
4
4
 
5
5
  Git-backed requirements and change history for coding agents. New projects use `schemaVersion: 1`, Markdown specifications and per-feature change reasons. Requires Node.js 24.x and Git.
6
6
 
7
- Install with `npm install -g gitifact`. Load the installed gitifact-workflow skill in the current agent session.
7
+ Install with `npm install -g gitifact`. Run `gitifact init`, then read the GITIFACT block it writes into the project's agent instruction file and follow it in the current session.
8
8
 
9
9
  ```sh
10
10
  gitifact init --dry-run
11
11
  gitifact init
12
- gitifact skills install --agent codex
12
+ gitifact docs
13
+ gitifact docs spec
13
14
  gitifact spec working
14
15
  gitifact spec save --file input.json
15
16
  gitifact spec changes
@@ -19,11 +20,13 @@ gitifact spec read --ref HEAD
19
20
  gitifact spec diff --from BEFORE --to AFTER
20
21
  ```
21
22
 
22
- Initialization creates only configuration and the Git adoption baseline. It requires Git, accepts an unborn repository, preserves unrelated work and staging, and never performs a commit. Existing legacy configuration requires an explicit separate transition. Skill installation preserves edited sources; the agent handles AGENTS.md/CLAUDE.md linkage and reads the installed skill in the current session.
23
+ Initialization creates the configuration and the Git adoption baseline, then installs a managed block between `<!-- GITIFACT:START -->` and `<!-- GITIFACT:END -->` in the agent instruction files. Existing `AGENTS.md`, `CLAUDE.md`, `.claude/CLAUDE.md`, `.cursorrules`, `.hermes.md` and `HERMES.md` all receive the block, except files that only `@`-import another one; when none exist, `AGENTS.md` is created. `--agent claude|cursor|codex|hermes|all` targets one tool's file instead, `--remove-agents` removes the block, and `--skip-agents` leaves instruction files alone. Text outside the markers is never touched; re-running `init` refreshes the block after a CLI update and refuses files with a broken marker pair. Initialization requires Git, accepts an unborn repository, preserves unrelated work and staging, and never performs a commit. Existing legacy configuration requires an explicit separate transition.
24
+
25
+ `gitifact docs` lists the guidance topics (`workflow`, `spec`, `design`, `product`, `commit`) and `gitifact docs <topic>` prints the bundled Markdown for one. The block summarises the rules and points agents at these topics for the exact input formats.
23
26
 
24
27
  The legacy `req`, `note`, `mode`, `brief`, `commit plan/apply` and `init --mode` commands and the `spec-preview` alias have been removed. Historical JSON projects require the old `gitifact@0.4.0` or earlier. `browser` serves requirement history, current features and contributors from Markdown/Git.
25
28
 
26
- The `spec` commands use the same input objects described by the installed workflow skill. Their output envelope is `contract: "spec", version: 1`. For a project with schemaVersion 1, config bytes are bound to working stamps and commit plans. Creation and edits never imply user approval or implementation completion.
29
+ The `spec` commands use the input objects described by `gitifact docs spec` and `gitifact docs commit`. Their output envelope is `contract: "spec", version: 1`. For a project with schemaVersion 1, config bytes are bound to working stamps and commit plans. Creation and edits never imply user approval or implementation completion.
27
30
 
28
31
  ## Browser
29
32
 
@@ -62,6 +65,6 @@ MIT. Bundled dependency notices are included in `dist/THIRD_PARTY_NOTICES.txt`.
62
65
 
63
66
  ## Feature designs
64
67
 
65
- The development build supports optional `design.md` next to requirements.md. The workflow skill creates both by default for new features. Add `{type: "set-design", feature, title, body}` to spec save operations; use `{type: "delete-design", feature}` to remove it. The CLI writes the owning S-ID, while explicit `gitifact-ref` annotations link actual R-IDs. Missing current references return warnings.
68
+ The development build supports optional `design.md` next to requirements.md. `gitifact docs design` tells agents to create both by default for new features. Add `{type: "set-design", feature, title, body}` to spec save operations; use `{type: "delete-design", feature}` to remove it. The CLI writes the owning S-ID, while explicit `gitifact-ref` annotations link actual R-IDs. Missing current references return warnings.
66
69
 
67
70
  Commit reasons may add `designs: ["S-…"]` alongside `requirements`. For a design-only reason, use `requirements: []`. Design changes have `kind: "design"` and do not become requirement changes. Use spec commit; deprecated commit-plan/apply do not accept new design changes. The browser displays designs in feature tabs and specification history. This extension is not yet published.
@@ -1 +1 @@
1
- import{c as e}from"./themeProps-BV289t6M.js";import{t}from"./Text-LX6541eF.js";import{t as n,u as r,yt as i}from"./page-header-it9YqWBS.js";var a=e();function o(){return(0,a.jsxs)(r,{gap:0,children:[(0,a.jsx)(n,{trail:[{label:`gitifact 소개`}]}),(0,a.jsxs)(r,{padding:6,gap:5,maxWidth:`48rem`,children:[(0,a.jsx)(i,{level:1,children:`gitifact 소개`}),(0,a.jsx)(t,{children:`gitifact는 에이전트와 함께 만드는 프로젝트의 요구사항과 결정 이력을 Git에 남기는 도구입니다.`}),(0,a.jsx)(t,{children:`사용자는 제품에 집중하고, 에이전트는 대화에서 요구사항과 판단을 정리합니다. 이 화면에서 같은 기록을 읽고 변경의 맥락을 살펴보세요.`}),(0,a.jsx)(t,{color:`secondary`,children:`현재는 요구사항·확인 이력·판단 기록과 Git 상태를 읽습니다. 전체 커밋 연결, 검사 결과, 스킬 탐색은 이후 범위입니다.`})]})]})}var s=o;export{s as component};
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{t}from"./Text-LX6541eF.js";import{bt as n,d as r,t as i}from"./page-header-pnZFm0-7.js";var a=e();function o(){return(0,a.jsxs)(r,{gap:0,children:[(0,a.jsx)(i,{trail:[{label:`gitifact 소개`}]}),(0,a.jsxs)(r,{padding:6,gap:5,maxWidth:`48rem`,children:[(0,a.jsx)(n,{level:1,children:`gitifact 소개`}),(0,a.jsx)(t,{children:`gitifact는 에이전트와 함께 만드는 프로젝트의 요구사항과 결정 이력을 Git에 남기는 도구입니다.`}),(0,a.jsx)(t,{children:`사용자는 제품에 집중하고, 에이전트는 대화에서 요구사항과 판단을 정리합니다. 이 화면에서 같은 기록을 읽고 변경의 맥락을 살펴보세요.`}),(0,a.jsx)(t,{color:`secondary`,children:`현재는 요구사항·확인 이력·판단 기록과 Git 상태를 읽습니다. 전체 커밋 연결, 검사 결과, 스킬 탐색은 이후 범위입니다.`})]})]})}var s=o;export{s as component};
@@ -1 +1 @@
1
- import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-DAbLI-2U.js";import{r as n}from"./index-DMRG08Xu.js";var r=e();function i(){let e=n.useSearch(),{email:i}=n.useParams(),a=n.useNavigate();return(0,r.jsx)(t,{view:`contributors`,email:i,search:e,change:(e,t)=>{a({search:e,replace:t??!1})}})}export{i as component};
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{o as n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),{email:i}=n.useParams(),a=n.useNavigate();return(0,r.jsx)(t,{view:`contributors`,email:i,search:e,change:(e,t)=>{a({search:e,replace:t??!1})}})}export{i as component};
@@ -1 +1 @@
1
- import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-DAbLI-2U.js";import{i as n}from"./index-DMRG08Xu.js";var r=e();function i(){let e=n.useSearch(),i=n.useNavigate();return(0,r.jsx)(t,{view:`contributors`,search:e,change:(e,t)=>{i({search:e,replace:t??!1})}})}export{i as component};
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{s as n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),i=n.useNavigate();return(0,r.jsx)(t,{view:`contributors`,search:e,change:(e,t)=>{i({search:e,replace:t??!1})}})}export{i as component};
@@ -1 +1 @@
1
- import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-DAbLI-2U.js";import{t as n}from"./index-DMRG08Xu.js";var r=e();function i(){let e=n.useSearch(),{featureId:i}=n.useParams(),a=n.useNavigate();return(0,r.jsx)(t,{view:`features`,featureId:i,search:e,change:(e,t)=>{a({search:e,replace:t??!1})}})}export{i as component};
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{i as n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),{featureId:i}=n.useParams(),a=n.useNavigate();return(0,r.jsx)(t,{view:`features`,featureId:i,search:e,change:(e,t)=>{a({search:e,replace:t??!1})}})}export{i as component};
@@ -1 +1 @@
1
- import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-DAbLI-2U.js";import{a as n}from"./index-DMRG08Xu.js";var r=e();function i(){let e=n.useSearch(),i=n.useNavigate();return(0,r.jsx)(t,{view:`features`,search:e,change:(e,t)=>{i({search:e,replace:t??!1})}})}export{i as component};
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{a as n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),i=n.useNavigate();return(0,r.jsx)(t,{view:`features`,search:e,change:(e,t)=>{i({search:e,replace:t??!1})}})}export{i as component};
@@ -0,0 +1 @@
1
+ import{A as e,D as t,c as n}from"./themeProps-BV289t6M.js";import{C as r,_ as i,a,g as o,h as s,i as c,m as l,r as u,t as d}from"./request-state-q7VzEh1O.js";import{t as f}from"./Text-LX6541eF.js";import{f as p,t as m}from"./IconButton-DQKowV1I.js";import{A as h,E as g,L as _,N as v,P as y,S as b,a as x,bt as S,c as C,d as w,l as T,o as E,p as D,r as O,s as k,t as A,w as j}from"./page-header-pnZFm0-7.js";import{u as M}from"./index-Cul6rpdA.js";var N=class extends j{#e;#t=void 0;#n;#r;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#i()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),v(this.options,t)||this.#e.getMutationCache().notify({type:`observerOptionsUpdated`,mutation:this.#n,observer:this}),t?.mutationKey&&this.options.mutationKey&&g(t.mutationKey)!==g(this.options.mutationKey)?this.reset():this.#n?.state.status===`pending`&&this.#n.setOptions(this.options)}onSubscribe(){this.listeners.size===1&&this.#n&&(this.#n.addObserver(this),this.#i())}onUnsubscribe(){this.hasListeners()||this.#n?.removeObserver(this)}onMutationUpdate(e){this.#i(),this.#a(e)}getCurrentResult(){return this.#t}reset(){this.#n?.removeObserver(this),this.#n=void 0,this.#i(),this.#a()}mutate(e,t){return this.#r=t,this.#n?.removeObserver(this),this.#n=this.#e.getMutationCache().build(this.#e,this.options),this.#n.addObserver(this),this.#n.execute(e)}#i(){let e=this.#n?.state??M();this.#t={...e,isPending:e.status===`pending`,isSuccess:e.status===`success`,isError:e.status===`error`,isIdle:e.status===`idle`,mutate:this.mutate,reset:this.reset}}#a(e){b.batch(()=>{if(this.#r&&this.hasListeners()){let t=this.#t.variables,n=this.#t.context,r={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type===`success`){try{this.#r.onSuccess?.(e.data,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(e.data,null,t,n,r)}catch(e){Promise.reject(e)}}else if(e?.type===`error`){try{this.#r.onError?.(e.error,t,n,r)}catch(e){Promise.reject(e)}try{this.#r.onSettled?.(void 0,e.error,t,n,r)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#t)})})}},P=e(t(),1);function F(e,t){let n=_(t),[r]=P.useState(()=>new N(n,e));P.useEffect(()=>{r.setOptions(e)},[r,e]);let i=P.useSyncExternalStore(P.useCallback(e=>r.subscribe(b.batchCalls(e)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),a=P.useCallback((...e)=>{r.mutate(e[0],e[1]).catch(h)},[r]);if(i.error&&y(r.options.throwOnError,[i.error]))throw i.error;return{...i,mutate:a,mutateAsync:i.mutate}}var I={page:`_page_1zvug_2`,column:`_column_1zvug_3`,pageTitle:`_pageTitle_1zvug_4`,content:`_content_1zvug_5`,reveal:`_reveal_1zvug_1`,summary:`_summary_1zvug_8`,summaryItem:`_summaryItem_1zvug_9`,code:`_code_1zvug_10`,changes:`_changes_1zvug_11`,path:`_path_1zvug_12`},L=n();function R(e){if(e.kind===`unmerged`)return[{label:`충돌`,color:`red`}];if(e.kind===`untracked`||!e.xy)return[{label:`Untracked`,color:`gray`}];let t=[];return e.xy[0]!==`.`&&t.push({label:`Staged`,color:`green`}),e.xy[1]!==`.`&&t.push({label:`Unstaged`,color:`blue`}),t}function z(e){return e.submodule?[e.submodule.commitChanged&&`submodule 커밋 변경`,e.submodule.trackedChanges&&`내부 tracked 변경`,e.submodule.untrackedChanges&&`내부 untracked 변경`].filter(Boolean).join(`, `):null}function B({session:e,reconnect:t}){let n=_(),d=D(C(e)),h=F({mutationFn:()=>x(e),retry:!1,onMutate:async()=>{await n.cancelQueries({queryKey:k(e)})},onSuccess:async()=>{await n.cancelQueries({queryKey:k(e)}),await n.invalidateQueries({queryKey:k(e)})}}),g=h.error??d.error,v=g instanceof T&&(g.code===`SESSION_CHANGED`||g.code===`INVALID_RESPONSE`),y=v?void 0:d.data,b=h.isPending||d.isFetching,E=!!y?.changes.some(e=>e.submodule),j=[{key:`xy`,header:`상태`,width:l(150),renderCell:e=>(0,L.jsx)(O,{gap:1,wrap:`wrap`,children:R(e).map(e=>(0,L.jsx)(o,{label:e.label,color:e.color,size:`sm`},e.label))})},{key:`code`,header:`코드`,width:l(64),renderCell:e=>(0,L.jsx)(f,{type:`supporting`,color:`secondary`,className:I.code,children:e.xy??`??`})},{key:`path`,header:`경로`,width:s(1,{minWidth:160}),renderCell:e=>(0,L.jsx)(f,{className:I.path,children:e.path})}];E&&j.push({key:`submodule`,header:`추가 정보`,width:s(1),renderCell:e=>(0,L.jsx)(f,{type:`supporting`,color:`secondary`,children:z(e)??`—`})});let M=y?[[`Staged`,y.summary.staged],[`Unstaged`,y.summary.unstaged],[`Untracked`,y.summary.untracked],[`충돌`,y.summary.conflicted]]:[];return(0,L.jsxs)(w,{gap:0,className:I.page,"aria-busy":b,children:[(0,L.jsx)(A,{trail:[{label:`Git 상태`}],actions:(0,L.jsx)(m,{label:b?`조회 중…`:`상태 새로고침`,icon:(0,L.jsx)(i,{}),variant:`ghost`,size:`sm`,isLoading:b,isDisabled:b||v,onClick:()=>h.mutate()})}),(0,L.jsxs)(w,{gap:0,className:I.column,children:[(0,L.jsx)(w,{gap:1,className:I.pageTitle,children:(0,L.jsx)(S,{level:1,children:`Git 상태`})}),(0,L.jsxs)(w,{gap:5,className:I.content,"aria-label":`저장소 상태`,children:[g&&(0,L.jsxs)(w,{role:`alert`,gap:3,children:[(0,L.jsx)(f,{children:g.message}),v?(0,L.jsx)(O,{children:(0,L.jsx)(p,{label:`다시 연결`,onClick:t})}):y&&(0,L.jsx)(f,{type:`supporting`,color:`secondary`,children:`이전 조회 결과입니다. 마지막 확인 시각을 참고하세요.`})]}),!y&&d.isPending&&(0,L.jsx)(f,{role:`status`,type:`supporting`,color:`secondary`,children:`저장소 상태를 읽고 있습니다.`}),y&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(c,{columns:`multi`,children:[(0,L.jsx)(u,{label:`브랜치`,children:y.head.branch??`detached HEAD`}),(0,L.jsx)(u,{label:`HEAD`,children:y.head.commit?(0,L.jsx)(f,{className:I.code,children:y.head.commit.slice(0,10)}):`아직 커밋이 없습니다`}),(0,L.jsx)(u,{label:`저장소`,children:(0,L.jsx)(f,{className:I.path,children:y.repository.rootPath})}),(0,L.jsx)(u,{label:`마지막 확인`,children:(0,L.jsx)(`time`,{dateTime:y.observation.completedAt,children:new Date(y.observation.completedAt).toLocaleString()})})]}),(0,L.jsx)(O,{gap:6,wrap:`wrap`,"aria-label":`변경 집계`,className:I.summary,children:M.map(([e,t])=>(0,L.jsxs)(O,{gap:2,className:I.summaryItem,children:[(0,L.jsx)(f,{type:`supporting`,color:`secondary`,children:e}),(0,L.jsx)(f,{weight:`semibold`,children:t})]},e))}),y.changes.length===0?(0,L.jsx)(r,{isCompact:!0,title:`변경된 파일이 없습니다`,description:`작업 트리가 마지막 커밋과 같습니다.`}):(0,L.jsxs)(w,{gap:3,className:I.changes,children:[(0,L.jsxs)(f,{type:`supporting`,color:`secondary`,children:[`변경 경로 `,y.changes.length,`개 · 코드의 첫 글자는 staged, 두 번째는 unstaged이며 .은 변경 없음입니다.`]}),(0,L.jsx)(a,{data:y.changes,idKey:`path`,columns:j,density:`compact`,dividers:`rows`,textOverflow:`wrap`})]}),(0,L.jsxs)(O,{gap:3,wrap:`wrap`,children:[(0,L.jsx)(f,{type:`supporting`,color:`secondary`,children:`관측한 Git 상태이며 파일 내용을 고정한 스냅샷은 아닙니다.`}),(0,L.jsx)(f,{type:`supporting`,color:`secondary`,children:`gitifact 요구사항 검사는 아직 실행하지 않습니다.`})]})]})]})]})]})}function V(){let e=D(E()),t=_(),[n,r]=(0,P.useState)(0),i=async()=>{await t.cancelQueries({queryKey:[`repository-status`]}),t.removeQueries({queryKey:[`repository-status`]}),await e.refetch(),r(e=>e+1)};return e.data&&!e.error?(0,L.jsx)(B,{session:e.data,reconnect:()=>{i()}},e.data.sessionId+`:`+n):(0,L.jsxs)(w,{gap:0,className:I.page,children:[(0,L.jsx)(A,{trail:[{label:`Git 상태`}]}),(0,L.jsxs)(w,{gap:0,className:I.column,children:[(0,L.jsx)(w,{gap:1,className:I.pageTitle,children:(0,L.jsx)(S,{level:1,children:`Git 상태`})}),e.isPending&&(0,L.jsx)(w,{padding:5,children:(0,L.jsx)(f,{role:`status`,type:`supporting`,color:`secondary`,children:`로컬 서버에 연결하고 있습니다.`})}),e.error&&(0,L.jsx)(d,{error:e.error,retry:()=>{i()}})]})]})}var H=V;export{H as component};
@@ -0,0 +1 @@
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),{documentId:i}=n.useParams(),a=n.useNavigate();return(0,r.jsx)(t,{view:`guides`,documentId:i,search:e,change:(e,t)=>{a({search:e,replace:t??!1})}})}export{i as component};
@@ -0,0 +1 @@
1
+ import{c as e}from"./themeProps-BV289t6M.js";import{n as t}from"./product-B_C25r7E.js";import{r as n}from"./index-Cul6rpdA.js";var r=e();function i(){let e=n.useSearch(),i=n.useNavigate();return(0,r.jsx)(t,{view:`guides`,search:e,change:(e,t)=>{i({search:e,replace:t??!1})}})}export{i as component};