@aefree/pi-plastic 0.4.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 (61) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/CONTRIBUTING.md +88 -0
  3. package/LICENSE +21 -0
  4. package/README.md +181 -0
  5. package/SECURITY.md +31 -0
  6. package/evals/tool-loading/README.md +38 -0
  7. package/evals/tool-loading/RESULTS.md +57 -0
  8. package/evals/tool-loading/baseline.json +34 -0
  9. package/evals/tool-loading/cases.json +70 -0
  10. package/evals/tool-loading/config.json +19 -0
  11. package/evals/tool-loading/mutation-guard.ts +30 -0
  12. package/evals/tool-loading/provider-capture.ts +22 -0
  13. package/evals/tool-loading/results/.gitignore +3 -0
  14. package/evals/tool-loading/run-eval.ts +372 -0
  15. package/extensions/bash-cm-diff-guard.ts +49 -0
  16. package/extensions/bash-cm-merge-guard.ts +53 -0
  17. package/extensions/plastic-branch-status.ts +285 -0
  18. package/extensions/repository-search-provider.ts +66 -0
  19. package/extensions/shared/bash-command-guards.ts +67 -0
  20. package/index.ts +777 -0
  21. package/package.json +76 -0
  22. package/skills/_shared/references/conventional-commits.md +198 -0
  23. package/skills/using-plastic/SKILL.md +50 -0
  24. package/skills/using-plastic/references/branch-management.md +78 -0
  25. package/skills/using-plastic/references/changeset-operations.md +96 -0
  26. package/skills/using-plastic/references/code-review-creation.md +30 -0
  27. package/skills/using-plastic/references/integration.md +47 -0
  28. package/skills/using-plastic/references/quick-reference.md +32 -0
  29. package/skills/using-plastic/references/resources.md +7 -0
  30. package/skills/using-plastic/references/reviewing-changes.md +71 -0
  31. package/skills/using-plastic/references/shelving.md +25 -0
  32. package/skills/using-plastic/references/troubleshooting.md +115 -0
  33. package/skills/using-plastic/references/workspaces.md +33 -0
  34. package/src/pi-tool-compat.ts +56 -0
  35. package/src/plastic-core.ts +4204 -0
  36. package/src/plastic-tool-loading.ts +234 -0
  37. package/src/plastic-workspace.ts +176 -0
  38. package/src/repository-search-provider.ts +64 -0
  39. package/tests/bash-cm-diff-guard-validation.ts +55 -0
  40. package/tests/fixtures/plastic.selector +3 -0
  41. package/tests/fixtures/status-compact.txt +1 -0
  42. package/tests/fixtures/status-normal.txt +1 -0
  43. package/tests/packed-copy-owner-conflict.test.ts +28 -0
  44. package/tests/pi-tool-harness.ts +116 -0
  45. package/tests/plastic-branch-create-live.test.ts +78 -0
  46. package/tests/plastic-branch-query.test.ts +26 -0
  47. package/tests/plastic-branch-status.test.ts +241 -0
  48. package/tests/plastic-checkin-path-resolution.ts +219 -0
  49. package/tests/plastic-constrained-sampling.test.ts +77 -0
  50. package/tests/plastic-diff-workflow.test.ts +86 -0
  51. package/tests/plastic-dynamic-tool-loading.test.ts +224 -0
  52. package/tests/plastic-extension-registration.test.ts +34 -0
  53. package/tests/plastic-live-smoke.test.ts +37 -0
  54. package/tests/plastic-mutation-execution.test.ts +61 -0
  55. package/tests/plastic-patch-command.test.ts +118 -0
  56. package/tests/plastic-process-lifecycle.test.ts +148 -0
  57. package/tests/plastic-tool-rendering.test.ts +16 -0
  58. package/tests/plastic-tool-validation.ts +153 -0
  59. package/tests/plastic-workspace.test.ts +62 -0
  60. package/tests/repository-search-provider-registration.test.ts +37 -0
  61. package/tests/repository-search-provider.test.ts +27 -0
@@ -0,0 +1,71 @@
1
+ # Reviewing Changes
2
+
3
+ ## Critical Rule
4
+
5
+ Never run `cm diff` in Pi. It may open a GUI window and block CLI automation.
6
+
7
+ `plastic_diff` is disabled by design.
8
+
9
+ ## Focused Patch Generation
10
+
11
+ Use `plastic_patch` when you need a branch-review patch for AI assistance, code review, or sharing outside the Plastic GUI:
12
+
13
+ ```text
14
+ plastic_patch(source="<branch-spec>", integration=true)
15
+ plastic_patch(source="<branch-spec>", clean=true, integration=true, output="<patch-file>")
16
+ plastic_patch(source="<left-spec>", destination="<right-spec>")
17
+ plastic_patch(source="<branch-spec>", toolPath="<path-to-diff-tool>")
18
+ ```
19
+
20
+ `integration=true` shows changes pending merge into the parent branch. `clean=true` strips content that arrived via merges. Use `output` for large patches; Plastic refuses to overwrite an existing output file. Inspect patch contents before sharing because patches can contain source code, binary data, local paths, or secrets present in changed files.
21
+
22
+ ## Text-Only Diff Options
23
+
24
+ Prefer tool-first:
25
+
26
+ ```text
27
+ plastic_status(machineReadable=true) # “what changed?” / changed-path listing
28
+ plastic_diffFile(path="<workspace-path>") # common workspace vs Plastic-base comparison
29
+ plastic_diffFile(path="<workspace-path>", revision="cs:<number>") # explicit advanced comparison
30
+ plastic_diffRevisions(leftRevision="<left-file-qualified-revspec>", rightRevision="<right-file-qualified-revspec>")
31
+ ```
32
+
33
+ The diff tools materialize historical bytes and remove their temporary files internally. They use a bounded portable text diff, treat valid Unity YAML as text, and report genuine binary content explicitly. Do not construct `cm cat` temporary-file recipes for ordinary review.
34
+
35
+ ## Metadata Listing (No GUI Diff)
36
+
37
+ Use changeset metadata to understand branch activity:
38
+
39
+ ```bash
40
+ cm find changeset "where branch = '<branch-name>' order by changesetid desc limit 20" --format="{changesetid} {owner} {date} {comment}" --nototal
41
+ ```
42
+
43
+ ## Read Files Directly
44
+
45
+ Use the Read tool for full context instead of GUI diffs.
46
+
47
+ ## CLI-Safe File Diff
48
+
49
+ Use the common no-revision path first; `base`, `head`, and `cs:head` are rejected rather than guessed:
50
+
51
+ ```text
52
+ plastic_diffFile(path="<workspace-path>")
53
+ plastic_diffFile(path="<workspace-path>", revision="br:/<branch>")
54
+ plastic_diffRevisions(leftRevision="<left-file-qualified-revspec>", rightRevision="<right-file-qualified-revspec>")
55
+ ```
56
+
57
+ ## Pending Changes
58
+
59
+ Prefer tool-first:
60
+
61
+ ```text
62
+ plastic_status()
63
+ ```
64
+
65
+ Manual shell fallback:
66
+
67
+ ```bash
68
+ cm status --all
69
+ ```
70
+
71
+ When pending changes include deletions, verify deleted paths in status output before checkin.
@@ -0,0 +1,25 @@
1
+ # Shelving
2
+
3
+ ## Save Work
4
+
5
+ ```bash
6
+ cm shelveset create -c="Working on feature X"
7
+ ```
8
+
9
+ ## List Shelves
10
+
11
+ ```bash
12
+ cm find shelve "where owner='me'" --format="{shelveid} {date} {comment}"
13
+ ```
14
+
15
+ ## Restore Work
16
+
17
+ ```bash
18
+ cm shelveset apply sh:5
19
+ ```
20
+
21
+ ## Delete Shelve
22
+
23
+ ```bash
24
+ cm shelveset delete sh:5
25
+ ```
@@ -0,0 +1,115 @@
1
+ # Troubleshooting
2
+
3
+ ## Branch Already Exists
4
+
5
+ ```bash
6
+ cm find branch "where name='<branch-name>'"
7
+ ```
8
+
9
+ ## Cannot Switch (Pending Changes)
10
+
11
+ ```bash
12
+ cm shelveset create --all -c="Auto-save before switch"
13
+ cm switch --silent --noinput <branch-spec>
14
+ ```
15
+
16
+ - In unattended mode, `pendingChanges="bring"` is blocked only when tracked pending changes exist.
17
+ - Private-only pending changes do not require interactive bring; `plastic_switchBranch` now performs a direct switch.
18
+ - `pendingChanges="shelve"` may report `There are no changes in the workspace` when pending items are private-only;
19
+ the tool recovers by skipping shelve and switching directly.
20
+
21
+ Agent preference: use runtime `plastic_*` methods first; keep shell commands as manual fallback.
22
+
23
+ ## Code Review Creation Failed
24
+
25
+ - Use GUI or document changeset in plan/issue tracker.
26
+
27
+ ## Reviewer Not Assigned
28
+
29
+ - Reviewer assignment is required for code review workflow.
30
+ - Preferred: gather branch/status via `plastic_status()` first, then assign reviewer in review edit flow.
31
+ - Shell fallback:
32
+
33
+ ```bash
34
+ cm codereview -e <review-id> --reviewer="reviewer-name"
35
+ ```
36
+
37
+ - If the reviewer flag differs in your server, use `cm codereview --help` and apply the equivalent reviewer option.
38
+
39
+ ## GUI Opens When Using cm diff
40
+
41
+ - `cm diff` is blocked in Pi because it can launch GUI windows and hang the CLI.
42
+ - Use text-only alternatives:
43
+ - `plastic_status(machineReadable=true)` for changed paths/statuses.
44
+ - `plastic_diffFile(path="<workspace-path>")` for the common workspace-base comparison.
45
+ - `plastic_diffFile(path="<workspace-path>", revision="cs:<number>")` for an explicit supported revision.
46
+ - `plastic_diffRevisions(leftRevision="<left-file-qualified-revspec>", rightRevision="<right-file-qualified-revspec>")` for two historical files.
47
+
48
+ ## GUI/Prompt Opens During Merge
49
+
50
+ - Do not run interactive `cm merge --merge` in Pi.
51
+ - Preferred:
52
+
53
+ ```text
54
+ plastic_merge(source="<source-branch-spec>")
55
+ ```
56
+
57
+ - Shell fallback must be non-interactive and use safe auto-resolution:
58
+
59
+ ```bash
60
+ cm merge <source-branch-spec> --merge --nointeractiveresolution --mergetype=try
61
+ ```
62
+
63
+ - Explicit override (only when intentional):
64
+
65
+ ```text
66
+ plastic_merge(source="<source-branch-spec>", strategy="destination")
67
+ plastic_merge(source="<source-branch-spec>", strategy="source")
68
+ ```
69
+
70
+ - If Plastic reports a delete/change directory conflict and you intentionally want to accept the source-side deletion, use:
71
+
72
+ ```text
73
+ plastic_resolveDeleteChangeConflict(paths=["<workspace-path>"], keepOnDisk=true)
74
+ ```
75
+
76
+ - Then rerun `plastic_merge(...)`.
77
+ - Even when `plastic_merge(...)` reports success, run `plastic_status()` before checkin. Merge output is not authoritative if Plastic still reports merge state.
78
+
79
+ ## Merge Checkin Says Merge Is Still In Progress
80
+
81
+ - Symptom:
82
+ - `plastic_merge(...)` reports `FILE_CONFLICT` paths or checkin later fails with a merge-in-progress error.
83
+ - The files have been reviewed/resolved and compile/tests pass.
84
+ - `plastic_status()` still shows pending merge metadata.
85
+ - Treat `plastic_status()` merge-state hints as the source of truth. Pending merge links are expected until checkin; explicit merge-in-progress hints are blockers.
86
+ - Recovery flow:
87
+ 1. Run `plastic_status()` and inspect merge-state details plus any `FILE_CONFLICT` paths reported by `plastic_merge(...)`.
88
+ 2. Resolve/review the listed files manually and run compile/tests as appropriate.
89
+ 3. Run `plastic_finalizeMerge(source="<source-branch-spec>", strategy="destination")` to finalize Plastic merge metadata while preserving the reviewed destination/manual result. Use `strategy="source"` only when accepting source is intentional.
90
+ 4. Run `plastic_status()` again.
91
+ 5. Retry `plastic_checkin(...)` after merge-in-progress hints are gone.
92
+ - If you are unsure whether the reviewed workspace result will be preserved, create a shelveset before finalizing.
93
+
94
+ ## Invalid cm diff --summary Usage
95
+
96
+ - Do not use `cm diff --summary`; this form is invalid.
97
+ - Also avoid all other `cm diff` forms in Pi.
98
+ - Use the same text-only alternatives listed above.
99
+
100
+ ## Deleted Files Missing From Checkin
101
+
102
+ - Run `cm status --all` and confirm deleted items are listed before checkin.
103
+ - Use `plastic_checkin(preflight=true, paths=[...])` first; the tool can auto-rewrite moved/deleted file scopes to parent directories.
104
+ - If a path-scoped checkin is rejected as "not changed", rerun with `applyChanged=true` and a parent-directory scope.
105
+ - Re-run `cm status --all` just before checkin to validate scope.
106
+
107
+ ## Checkin says "No changes" but files were expected
108
+
109
+ - `includeAll=true` does not include private items automatically.
110
+ - `plastic_checkin` now pre-checks machine-readable status and can auto-add safe private files in scope,
111
+ then retry checkin once when Plastic returns `There are no changes in the workspace`.
112
+ - If only sensitive private paths are found (for example `.env*`, key material, `.npmrc`, credentials/secrets JSON),
113
+ auto-add is blocked and the tool returns an actionable error requiring explicit add/include choice.
114
+ - Check JSON metadata fields (`decisionPath`, `prePendingSummary`, `postPendingSummary`, `autoAddedPrivatePaths`,
115
+ `blockedPrivateAutoAddPaths`) to understand what unattended recovery path was used.
@@ -0,0 +1,33 @@
1
+ # Review Workspaces
2
+
3
+ ## Strategy
4
+
5
+ - Use a separate review workspace for isolation.
6
+ - Reuse `-review-1` by default (Unity workspaces are large).
7
+
8
+ ## Create or Reuse
9
+
10
+ ```bash
11
+ main_workspace=$(basename "$PWD")
12
+ review_workspace_name="${main_workspace}-review-1"
13
+ review_workspace="../${review_workspace_name}"
14
+
15
+ if [ -d "$review_workspace" ]; then
16
+ cd "$review_workspace"
17
+ cm switch --silent --noinput "$review_branch" || {
18
+ cm shelveset create --all -c="Auto-shelve before review switch"
19
+ cm switch --silent --noinput "$review_branch"
20
+ }
21
+ else
22
+ repo_spec=$(cm status --wkconfig | grep "^Repository:" | cut -d: -f2- | xargs)
23
+ cm workspace create "$review_workspace_name" "$review_workspace" "$repo_spec"
24
+ cd "$review_workspace"
25
+ cm switch --silent --noinput "$review_branch"
26
+ fi
27
+ ```
28
+
29
+ Agent preference: use runtime `plastic_*` methods first for branch/status operations; keep shell commands as manual fallback.
30
+
31
+ ## Cleanup
32
+
33
+ Only remove review workspaces when disk space is tight or requested.
@@ -0,0 +1,56 @@
1
+ type SchemaNode = {
2
+ kind: string;
3
+ values?: unknown;
4
+ inner?: unknown;
5
+ metadata?: Record<string, unknown>;
6
+ optional(): SchemaNode;
7
+ describe(description: string): SchemaNode;
8
+ min(value: number): SchemaNode;
9
+ max(value: number): SchemaNode;
10
+ int(): SchemaNode;
11
+ };
12
+
13
+ function createSchemaNode(kind: string, values?: unknown, inner?: unknown): SchemaNode {
14
+ const node: SchemaNode = {
15
+ kind,
16
+ values,
17
+ inner,
18
+ metadata: {},
19
+ optional() {
20
+ this.metadata = { ...(this.metadata ?? {}), optional: true };
21
+ return this;
22
+ },
23
+ describe(description: string) {
24
+ this.metadata = { ...(this.metadata ?? {}), description };
25
+ return this;
26
+ },
27
+ min(value: number) {
28
+ this.metadata = { ...(this.metadata ?? {}), min: value };
29
+ return this;
30
+ },
31
+ max(value: number) {
32
+ this.metadata = { ...(this.metadata ?? {}), max: value };
33
+ return this;
34
+ },
35
+ int() {
36
+ this.metadata = { ...(this.metadata ?? {}), int: true };
37
+ return this;
38
+ },
39
+ };
40
+ return node;
41
+ }
42
+
43
+ export const tool = Object.assign(
44
+ <T extends Record<string, unknown>>(definition: T): T => definition,
45
+ {
46
+ schema: {
47
+ string: () => createSchemaNode("string"),
48
+ number: () => createSchemaNode("number"),
49
+ boolean: () => createSchemaNode("boolean"),
50
+ any: () => createSchemaNode("any"),
51
+ enum: (values: readonly unknown[]) => createSchemaNode("enum", [...values]),
52
+ union: (values: readonly unknown[]) => createSchemaNode("union", [...values]),
53
+ array: (inner: unknown) => createSchemaNode("array", undefined, inner),
54
+ },
55
+ },
56
+ );