@aefree/pi-plastic 0.4.0 → 0.5.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.
- package/CHANGELOG.md +17 -0
- package/README.md +8 -7
- package/extensions/bash-cm-diff-guard.ts +2 -1
- package/extensions/file-discovery-filter.ts +67 -0
- package/index.ts +12 -0
- package/package.json +7 -8
- package/skills/_shared/references/conventional-commits.md +198 -198
- package/skills/using-plastic/SKILL.md +2 -2
- package/skills/using-plastic/references/changeset-operations.md +2 -1
- package/skills/using-plastic/references/code-review-creation.md +30 -30
- package/skills/using-plastic/references/integration.md +2 -1
- package/skills/using-plastic/references/quick-reference.md +2 -1
- package/skills/using-plastic/references/resources.md +7 -7
- package/skills/using-plastic/references/reviewing-changes.md +4 -3
- package/skills/using-plastic/references/shelving.md +25 -25
- package/skills/using-plastic/references/troubleshooting.md +2 -1
- package/skills/using-plastic/references/workspaces.md +33 -33
- package/src/file-discovery-filter-rendezvous.ts +104 -0
- package/src/{repository-search-provider.ts → file-discovery-filter.ts} +21 -17
- package/src/plastic-core.ts +438 -152
- package/src/plastic-tool-loading.ts +2 -1
- package/evals/tool-loading/README.md +0 -38
- package/evals/tool-loading/RESULTS.md +0 -57
- package/evals/tool-loading/baseline.json +0 -34
- package/evals/tool-loading/cases.json +0 -70
- package/evals/tool-loading/config.json +0 -19
- package/evals/tool-loading/mutation-guard.ts +0 -30
- package/evals/tool-loading/provider-capture.ts +0 -22
- package/evals/tool-loading/results/.gitignore +0 -3
- package/evals/tool-loading/run-eval.ts +0 -372
- package/extensions/repository-search-provider.ts +0 -66
- package/tests/bash-cm-diff-guard-validation.ts +0 -55
- package/tests/fixtures/plastic.selector +0 -3
- package/tests/fixtures/status-compact.txt +0 -1
- package/tests/fixtures/status-normal.txt +0 -1
- package/tests/packed-copy-owner-conflict.test.ts +0 -28
- package/tests/pi-tool-harness.ts +0 -116
- package/tests/plastic-branch-create-live.test.ts +0 -78
- package/tests/plastic-branch-query.test.ts +0 -26
- package/tests/plastic-branch-status.test.ts +0 -241
- package/tests/plastic-checkin-path-resolution.ts +0 -219
- package/tests/plastic-constrained-sampling.test.ts +0 -77
- package/tests/plastic-diff-workflow.test.ts +0 -86
- package/tests/plastic-dynamic-tool-loading.test.ts +0 -224
- package/tests/plastic-extension-registration.test.ts +0 -34
- package/tests/plastic-live-smoke.test.ts +0 -37
- package/tests/plastic-mutation-execution.test.ts +0 -61
- package/tests/plastic-patch-command.test.ts +0 -118
- package/tests/plastic-process-lifecycle.test.ts +0 -148
- package/tests/plastic-tool-rendering.test.ts +0 -16
- package/tests/plastic-tool-validation.ts +0 -153
- package/tests/plastic-workspace.test.ts +0 -62
- package/tests/repository-search-provider-registration.test.ts +0 -37
- package/tests/repository-search-provider.test.ts +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project follows semantic versioning for public package releases.
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - 2026-08-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added dynamically loadable `plastic_workspaceDiff` for bounded pending review: one machine-readable status pass, per-file text/binary/unavailable outcomes, selected-path and private-file policy, and intentional file/output limits.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Kept GNU/POSIX `diff` as the only text-diff backend, improved `PI_PLASTIC_DIFF_EXECUTABLE`/bare-PATH diagnostics (including Windows-like missing-diff guidance), and removed unused Git diff fallback code.
|
|
17
|
+
- Made workspace `plastic_diffFile` use machine-readable pending status for private/new, added, changed, moved, and deleted comparisons; status revision IDs materialize safe bases and `--nodata` base failures now explain recovery.
|
|
18
|
+
- Updated diff routing guidance: changed listing uses `plastic_status`, one file uses `plastic_diffFile`, pending review uses `plastic_workspaceDiff`, and explicit historical pairs use `plastic_diffRevisions`.
|
|
19
|
+
|
|
20
|
+
- Replaced the optional `@aefree/pi-repo-search` integration with `@aefree/pi-file-discovery`. Plastic ignore/cloak data is now an advisory file-discovery filter: only roots with readable ignore/cloak files emit `filterDecision: "applied"` records with a nearest-workspace `filterBoundary`; no-op roots are omitted and unavailable or malformed filter data degrades to generic discovery as routine execution hygiene.
|
|
21
|
+
- Register the optional Plastic filter through the package-qualified global capability-registry rendezvous instead of importing `pi-file-discovery` from Plastic's separate module root. Registration remains session-scoped, transactional, and safe against stale shutdown tokens.
|
|
22
|
+
- Excluded development-only tests and behavioral evals from published npm artifacts.
|
|
23
|
+
- Publish verified GitHub releases to npm through resumable OIDC trusted-publishing automation, and canonicalized the package repository URL for GitHub identity matching.
|
|
24
|
+
|
|
8
25
|
## [0.4.0] - 2026-08-01
|
|
9
26
|
|
|
10
27
|
### Added
|
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@ When Pi starts inside a Plastic workspace, this package adds a themed `Plastic <
|
|
|
8
8
|
|
|
9
9
|
The extension owns only the `plastic-branch` status key. It does not replace Pi's footer or suppress Pi's Git branch display, so Git and Plastic information can appear together in nested workspaces. If the Plastic marker exists but neither the selector nor `cm` yields a branch, the footer shows `Plastic branch unavailable`. Non-Plastic directories show no Plastic status.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## File-discovery filter
|
|
12
12
|
|
|
13
|
-
When `@aefree/pi-
|
|
13
|
+
When `@aefree/pi-file-discovery` is also loaded, Pi session startup registers the independent advisory `plastic.ignore-files` file-discovery filter through the package-qualified capability-registry rendezvous key. The packages may have separate module roots; Plastic does not import file-discovery from its own root. It discovers readable `ignore.conf` and `cloaked.conf` only from the nearest Plastic workspace to each requested root, then supplies them as ripgrep ignore files without replacing native ripgrep/Git-ignore behavior. A root is emitted only when it has at least one readable ignore/cloak file; each emitted root declares `filterDecision: "applied"`, decision code `plastic_ignore_files_applied`, and that workspace as its `filterBoundary`. No-op Plastic roots are omitted from mixed requests, and a request with no effective ignore/cloak records is `not_applicable`. The integration is optional: without `pi-file-discovery`, all Plastic tools and skills still load and no filter registry is created. Missing, malformed, or unavailable Plastic filter data degrades to generic discovery; `pi-file-discovery` owns that execution hygiene and disclosure behavior. It does not register workflow guidance or perform Plastic CLI readiness checks; owning `plastic_*` tools validate their own workspace and CLI requirements.
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
## Mutation execution
|
|
@@ -32,6 +32,7 @@ Removing the approval layer does not relax Plastic safety guards. Command allowl
|
|
|
32
32
|
- `plastic_patch`
|
|
33
33
|
- `plastic_diffRevisions`
|
|
34
34
|
- `plastic_diffFile`
|
|
35
|
+
- `plastic_workspaceDiff`
|
|
35
36
|
- `plastic_branchCreate`
|
|
36
37
|
- `plastic_switchBranch`
|
|
37
38
|
- `plastic_merge`
|
|
@@ -53,7 +54,7 @@ Removing the approval layer does not relax Plastic safety guards. Command allowl
|
|
|
53
54
|
|
|
54
55
|
## Dynamic tool loading
|
|
55
56
|
|
|
56
|
-
The package exposes
|
|
57
|
+
The package exposes 29 public `plastic_*` tools. `plastic_workspaceCreate` is intentionally not registered or discoverable until the package provides a paired, safe workspace-cleanup capability. `plastic_tool_search` is a package-owned loader that searches the explicit Plastic capability catalog, reports bounded matches and safety guidance, and additively enables selected tools for the next model request.
|
|
57
58
|
|
|
58
59
|
The default **balanced** session set keeps `plastic_tool_search`, `plastic_status`, and `plastic_currentBranch` active. The other Plastic tools remain registered but inactive until selected; built-in and other-extension tools are not removed. Previous loader additions on the active session branch are restored on startup, resume, fork, and reload.
|
|
59
60
|
|
|
@@ -62,7 +63,7 @@ For controlled comparisons, set `PI_PLASTIC_TOOL_LOADING_MODE` before starting P
|
|
|
62
63
|
```bash
|
|
63
64
|
PI_PLASTIC_TOOL_LOADING_MODE=balanced # default production candidate
|
|
64
65
|
PI_PLASTIC_TOOL_LOADING_MODE=loader-only # maximum initial schema reduction
|
|
65
|
-
PI_PLASTIC_TOOL_LOADING_MODE=all-active # all
|
|
66
|
+
PI_PLASTIC_TOOL_LOADING_MODE=all-active # all 29 currently exposed tools; loader omitted
|
|
66
67
|
```
|
|
67
68
|
|
|
68
69
|
Pi 0.82 and newer use canonical `sourceInfo` provenance to identify this package's effective tools before deferring, restoring, or activating them. If canonical provenance or ownership of the effective loader cannot be proven, `pi-plastic` fails safe: it preserves the complete current active set exactly, does not defer, remove, or activate any `plastic_*` name, and an effective package loader can only report known tools that are already active rather than activating inactive names. On sourceInfo-capable Pi instances, providers without native deferred definitions still receive the complete current active set after a loader call. Reload or restart Pi after source edits; source files are not watched automatically.
|
|
@@ -70,7 +71,7 @@ Pi 0.82 and newer use canonical `sourceInfo` provenance to identify this package
|
|
|
70
71
|
## Safety behavior
|
|
71
72
|
|
|
72
73
|
- `plastic_branchCreate` supports an explicit parent branch independent of the loaded workspace branch, defaults relative names to the current branch when no parent is supplied, and rejects top-level paths unless `allowRootBranch=true` is explicit.
|
|
73
|
-
- `plastic_diff` remains a disabled alias by design; use `plastic_diffFile` or `plastic_diffRevisions` for
|
|
74
|
+
- `plastic_diff` remains a disabled alias by design; use `plastic_status` for changed-path listing, `plastic_diffFile` for one file, `plastic_workspaceDiff` for pending review, or `plastic_diffRevisions` for an explicit historical pair.
|
|
74
75
|
- `plastic_patch` generates review patches with `cm patch`, including `clean` and `integration` filters for branch review workflows. It does not expose patch apply.
|
|
75
76
|
- Bash safety rails block `cm diff` and unsafe interactive `cm merge --merge` usage.
|
|
76
77
|
- Merge tooling surfaces Plastic `FILE_CONFLICT` records and merge-state metadata from `cm status`.
|
|
@@ -129,9 +130,9 @@ pi install -l <path-to-pi-plastic>
|
|
|
129
130
|
- Node.js 22.19.0 or newer
|
|
130
131
|
- Pi 0.82.0 or newer; the current development and eval baseline is Pi 0.83
|
|
131
132
|
- Plastic SCM / Unity Version Control CLI (`cm`) available on `PATH`, or `PI_PLASTIC_CM_EXECUTABLE` set to its full executable path
|
|
132
|
-
-
|
|
133
|
+
- GNU/POSIX-compatible `diff` available on `PATH`, or `PI_PLASTIC_DIFF_EXECUTABLE` set to its full executable path (including paths containing spaces), for text-only diff and patch tools. Pi does not discover Git Bash paths automatically.
|
|
133
134
|
- A configured Plastic workspace for workspace-scoped operations
|
|
134
|
-
-
|
|
135
|
+
- `pi-file-discovery` is an optional independently loaded integration. When its `discover_candidate_files` tool is active, it receives the advisory Plastic ignore/cloak filter through the shared global capability protocol; when absent, `pi-plastic` loads without file-discovery filtering. The tarball does not embed linked sibling workspaces or `node_modules` paths.
|
|
135
136
|
|
|
136
137
|
## Testing
|
|
137
138
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./shared/bash-command-guards";
|
|
7
7
|
|
|
8
8
|
const BLOCK_MESSAGE =
|
|
9
|
-
"`cm diff` is blocked in Pi because it can launch a GUI window and hang CLI automation. Use `plastic_status` to list changed paths, `plastic_diffFile` for
|
|
9
|
+
"`cm diff` is blocked in Pi because it can launch a GUI window and hang CLI automation. Use `plastic_status` to list changed paths, `plastic_diffFile` for one file, `plastic_workspaceDiff` for pending review, or `plastic_diffRevisions` for two explicit revisions.";
|
|
10
10
|
|
|
11
11
|
const DIRECT_CM_DIFF = /^(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+)*(?:(?:"[^"]*[\\/]cm(?:\.exe)?"|'[^']*[\\/]cm(?:\.exe)?')|(?:[^"'\s]*[\\/])?cm(?:\.exe)?)\s+diff(?:\s|$)/i;
|
|
12
12
|
|
|
@@ -24,6 +24,7 @@ function commandRunsCmDiff(command: string): boolean {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export const __bashCmDiffGuardInternals = {
|
|
27
|
+
blockMessage: BLOCK_MESSAGE,
|
|
27
28
|
segmentRunsCmDiff,
|
|
28
29
|
commandRunsCmDiff,
|
|
29
30
|
stripAssignments,
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { createPlasticFileDiscoveryFilterV1, loadPlasticOwnerV1 } from "../src/file-discovery-filter.ts";
|
|
3
|
+
import {
|
|
4
|
+
createPlasticFileDiscoveryFilterRegistryV1,
|
|
5
|
+
type PlasticFileDiscoveryRegistrationToken,
|
|
6
|
+
} from "../src/file-discovery-filter-rendezvous.ts";
|
|
7
|
+
|
|
8
|
+
type ScopeRegistration = Readonly<{ token: PlasticFileDiscoveryRegistrationToken }>;
|
|
9
|
+
type ScopeLifecycle = { generation: number; active: boolean };
|
|
10
|
+
|
|
11
|
+
function hasFileDiscoveryTool(pi: Pick<ExtensionAPI, "getActiveTools">): boolean {
|
|
12
|
+
return pi.getActiveTools?.().includes("discover_candidate_files") ?? false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Session-scoped optional Plastic file-discovery filter registration.
|
|
17
|
+
*
|
|
18
|
+
* Independently loaded packages rendezvous through the published global
|
|
19
|
+
* capability-registry protocol. No import is attempted from Plastic's module
|
|
20
|
+
* root, so an absent file-discovery package leaves Plastic unchanged.
|
|
21
|
+
*/
|
|
22
|
+
export function createPlasticFileDiscoveryFilterExtension(): (pi: ExtensionAPI) => void {
|
|
23
|
+
return (pi) => {
|
|
24
|
+
const registrations = new WeakMap<object, ScopeRegistration>();
|
|
25
|
+
const lifecycles = new WeakMap<object, ScopeLifecycle>();
|
|
26
|
+
|
|
27
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
28
|
+
if (!hasFileDiscoveryTool(pi)) return;
|
|
29
|
+
const scope = ctx.sessionManager;
|
|
30
|
+
const previous = lifecycles.get(scope);
|
|
31
|
+
const lifecycle = { generation: (previous?.generation ?? 0) + 1, active: true };
|
|
32
|
+
lifecycles.set(scope, lifecycle);
|
|
33
|
+
|
|
34
|
+
const owner = await loadPlasticOwnerV1(import.meta.url);
|
|
35
|
+
// Do not revive a scope whose shutdown occurred while owner discovery was pending.
|
|
36
|
+
if (lifecycles.get(scope) !== lifecycle || !lifecycle.active) return;
|
|
37
|
+
const registry = createPlasticFileDiscoveryFilterRegistryV1();
|
|
38
|
+
const token = registry.register(scope, createPlasticFileDiscoveryFilterV1(owner));
|
|
39
|
+
// Registration succeeds before the prior token is retired, preserving a valid
|
|
40
|
+
// record if construction or validation fails. Nonces make stale retirement safe.
|
|
41
|
+
const current = registrations.get(scope);
|
|
42
|
+
if (lifecycles.get(scope) !== lifecycle || !lifecycle.active) {
|
|
43
|
+
registry.unregister(token);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
registrations.set(scope, Object.freeze({ token }));
|
|
47
|
+
if (current !== undefined) registry.unregister(current.token);
|
|
48
|
+
});
|
|
49
|
+
pi.on("session_shutdown", (_event, ctx) => {
|
|
50
|
+
const scope = ctx.sessionManager;
|
|
51
|
+
const lifecycle = lifecycles.get(scope);
|
|
52
|
+
if (lifecycle !== undefined) {
|
|
53
|
+
lifecycle.active = false;
|
|
54
|
+
lifecycle.generation += 1;
|
|
55
|
+
}
|
|
56
|
+
const current = registrations.get(scope);
|
|
57
|
+
if (current === undefined) return;
|
|
58
|
+
createPlasticFileDiscoveryFilterRegistryV1().unregister(current.token);
|
|
59
|
+
// A stale shutdown must not erase a replacement registration.
|
|
60
|
+
if (registrations.get(scope) === current) registrations.delete(scope);
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default function registerPlasticFileDiscoveryFilters(pi: ExtensionAPI): void {
|
|
66
|
+
createPlasticFileDiscoveryFilterExtension()(pi);
|
|
67
|
+
}
|
package/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ const PLASTIC_EXPORTS = [
|
|
|
64
64
|
"patch",
|
|
65
65
|
"diffRevisions",
|
|
66
66
|
"diffFile",
|
|
67
|
+
"workspaceDiff",
|
|
67
68
|
"branchCreate",
|
|
68
69
|
"switchBranch",
|
|
69
70
|
"merge",
|
|
@@ -181,6 +182,17 @@ const TOOL_CONFIG: Partial<Record<PlasticExportName, ToolConfig>> = {
|
|
|
181
182
|
return input;
|
|
182
183
|
},
|
|
183
184
|
},
|
|
185
|
+
workspaceDiff: {
|
|
186
|
+
prepareArguments(args) {
|
|
187
|
+
const input = normalizeOutputFormatAlias(normalizeArgs(args));
|
|
188
|
+
normalizeWorkdirAliases(input);
|
|
189
|
+
promoteSinglePath(input);
|
|
190
|
+
assignAlias(input, "paths", ["items", "files"]);
|
|
191
|
+
assignAlias(input, "includePrivate", ["include_private"]);
|
|
192
|
+
assignAlias(input, "maxFiles", ["max_files"]);
|
|
193
|
+
return input;
|
|
194
|
+
},
|
|
195
|
+
},
|
|
184
196
|
branchCreate: {
|
|
185
197
|
prepareArguments(args) {
|
|
186
198
|
const input = normalizeArgs(args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aefree/pi-plastic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.19.0"
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
"src/",
|
|
18
18
|
"references/",
|
|
19
19
|
"skills/",
|
|
20
|
-
"evals/tool-loading/",
|
|
21
|
-
"tests/",
|
|
22
20
|
"CHANGELOG.md",
|
|
23
21
|
"CONTRIBUTING.md",
|
|
24
22
|
"LICENSE",
|
|
@@ -31,24 +29,25 @@
|
|
|
31
29
|
"./extensions/plastic-branch-status.ts",
|
|
32
30
|
"./extensions/bash-cm-diff-guard.ts",
|
|
33
31
|
"./extensions/bash-cm-merge-guard.ts",
|
|
34
|
-
"./extensions/
|
|
32
|
+
"./extensions/file-discovery-filter.ts"
|
|
35
33
|
],
|
|
36
34
|
"skills": [
|
|
37
35
|
"./skills"
|
|
38
36
|
]
|
|
39
37
|
},
|
|
40
38
|
"scripts": {
|
|
41
|
-
"test": "npx --yes tsx tests/plastic-tool-validation.ts && npx --yes tsx tests/plastic-checkin-path-resolution.ts && npx --yes tsx tests/plastic-diff-workflow.test.ts && npx --yes tsx tests/plastic-process-lifecycle.test.ts && npx --yes tsx tests/plastic-patch-command.test.ts && npx --yes tsx tests/plastic-extension-registration.test.ts && npx --yes tsx tests/plastic-dynamic-tool-loading.test.ts && npx --yes tsx tests/plastic-tool-rendering.test.ts && npx --yes tsx tests/plastic-branch-query.test.ts && npx --yes tsx tests/plastic-workspace.test.ts && npx --yes tsx tests/plastic-mutation-execution.test.ts && npx --yes tsx tests/
|
|
39
|
+
"test": "npx --yes tsx tests/plastic-tool-validation.ts && npx --yes tsx tests/plastic-checkin-path-resolution.ts && npx --yes tsx tests/plastic-diff-workflow.test.ts && npx --yes tsx tests/plastic-workspace-diff.test.ts && npx --yes tsx tests/plastic-process-lifecycle.test.ts && npx --yes tsx tests/plastic-patch-command.test.ts && npx --yes tsx tests/plastic-extension-registration.test.ts && npx --yes tsx tests/plastic-dynamic-tool-loading.test.ts && npx --yes tsx tests/plastic-tool-rendering.test.ts && npx --yes tsx tests/plastic-branch-query.test.ts && npx --yes tsx tests/plastic-workspace.test.ts && npx --yes tsx tests/plastic-mutation-execution.test.ts && npx --yes tsx tests/file-discovery-filter.test.ts && npx --yes tsx tests/file-discovery-filter-registration.test.ts && npx --yes tsx tests/packed-copy-owner-conflict.test.ts && npx --yes tsx tests/plastic-branch-status.test.ts && npx --yes tsx tests/plastic-constrained-sampling.test.ts && npx --yes tsx tests/bash-cm-diff-guard-validation.ts",
|
|
42
40
|
"test:live": "npx --yes tsx tests/plastic-live-smoke.test.ts",
|
|
43
41
|
"test:live:branch-create": "npx --yes tsx tests/plastic-branch-create-live.test.ts",
|
|
44
42
|
"eval:tool-loading": "npx --yes tsx evals/tool-loading/run-eval.ts"
|
|
45
43
|
},
|
|
46
44
|
"devDependencies": {
|
|
45
|
+
"@aefree/pi-file-discovery": "^0.1.1",
|
|
47
46
|
"@earendil-works/pi-coding-agent": "0.83.0",
|
|
48
47
|
"typebox": "^1.3.8"
|
|
49
48
|
},
|
|
50
49
|
"peerDependencies": {
|
|
51
|
-
"@aefree/pi-
|
|
50
|
+
"@aefree/pi-file-discovery": "^0.1.0",
|
|
52
51
|
"@earendil-works/pi-coding-agent": "*",
|
|
53
52
|
"typebox": "*"
|
|
54
53
|
},
|
|
@@ -56,14 +55,14 @@
|
|
|
56
55
|
"license": "MIT",
|
|
57
56
|
"repository": {
|
|
58
57
|
"type": "git",
|
|
59
|
-
"url": "git+
|
|
58
|
+
"url": "git+https://github.com/aefreedman/pi-plastic.git"
|
|
60
59
|
},
|
|
61
60
|
"bugs": {
|
|
62
61
|
"url": "https://github.com/aefreedman/pi-plastic/issues"
|
|
63
62
|
},
|
|
64
63
|
"homepage": "https://github.com/aefreedman/pi-plastic#readme",
|
|
65
64
|
"peerDependenciesMeta": {
|
|
66
|
-
"@aefree/pi-
|
|
65
|
+
"@aefree/pi-file-discovery": {
|
|
67
66
|
"optional": true
|
|
68
67
|
},
|
|
69
68
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -1,198 +1,198 @@
|
|
|
1
|
-
# Conventional Commits
|
|
2
|
-
|
|
3
|
-
This reference file documents the conventional commit format used across the project.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Format
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
<type>(<scope>): <subject>
|
|
11
|
-
|
|
12
|
-
[optional body]
|
|
13
|
-
|
|
14
|
-
[optional footer]
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Types
|
|
20
|
-
|
|
21
|
-
| Type | Description | Example |
|
|
22
|
-
|------|-------------|---------|
|
|
23
|
-
| **feat** | New feature | `feat(auth): add OAuth login` |
|
|
24
|
-
| **fix** | Bug fix | `fix(cart): calculate tax correctly` |
|
|
25
|
-
| **refactor** | Code restructuring (no behavior change) | `refactor(api): extract service layer` |
|
|
26
|
-
| **perf** | Performance improvement | `perf(query): optimize user lookup` |
|
|
27
|
-
| **test** | Adding or updating tests | `test(auth): add login edge cases` |
|
|
28
|
-
| **docs** | Documentation changes | `docs(readme): update installation steps` |
|
|
29
|
-
| **style** | Code style changes (formatting, etc.) | `style(lint): fix indentation` |
|
|
30
|
-
| **chore** | Build process or auxiliary tool changes | `chore(deps): update to Rails 7.1` |
|
|
31
|
-
| **ci** | CI/CD configuration changes | `ci(github): add test workflow` |
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Scope
|
|
36
|
-
|
|
37
|
-
The scope is optional but recommended. It specifies which part of the codebase was affected:
|
|
38
|
-
|
|
39
|
-
**Examples:**
|
|
40
|
-
- `feat(player): add dash mechanic`
|
|
41
|
-
- `fix(inventory): prevent negative quantities`
|
|
42
|
-
- `refactor(ui): simplify menu navigation`
|
|
43
|
-
- `perf(rendering): batch sprite draws`
|
|
44
|
-
|
|
45
|
-
**Guidelines:**
|
|
46
|
-
- Use lowercase
|
|
47
|
-
- Be specific but concise
|
|
48
|
-
- Match your module/component names
|
|
49
|
-
- Omit if change is global
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Subject
|
|
54
|
-
|
|
55
|
-
The subject contains a succinct description of the change:
|
|
56
|
-
|
|
57
|
-
- **Use imperative mood:** "add" not "added" or "adds"
|
|
58
|
-
- **Don't capitalize first letter:** "add feature" not "Add feature"
|
|
59
|
-
- **No period at the end:** "fix bug" not "fix bug."
|
|
60
|
-
- **Limit to 50 characters**
|
|
61
|
-
|
|
62
|
-
**Good examples:**
|
|
63
|
-
- `feat(auth): add password reset flow`
|
|
64
|
-
- `fix(api): handle null responses`
|
|
65
|
-
- `refactor(utils): extract string helpers`
|
|
66
|
-
|
|
67
|
-
**Bad examples:**
|
|
68
|
-
- `feat(auth): Added password reset flow` (not imperative)
|
|
69
|
-
- `feat(auth): Add Password Reset Flow` (capitalized)
|
|
70
|
-
- `feat(auth): add password reset flow.` (period at end)
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Body (Optional)
|
|
75
|
-
|
|
76
|
-
Use the body to explain **what** and **why**, not **how**:
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
feat(player): add dash mechanic
|
|
80
|
-
|
|
81
|
-
Adds a dash ability to the player character for enhanced mobility.
|
|
82
|
-
Dash has 1-second cooldown and consumes 10 stamina.
|
|
83
|
-
|
|
84
|
-
Closes #42
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Guidelines:**
|
|
88
|
-
- Wrap at 72 characters
|
|
89
|
-
- Separate from subject with blank line
|
|
90
|
-
- Focus on context and reasoning
|
|
91
|
-
- Link to issues if applicable
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## Footer (Optional)
|
|
96
|
-
|
|
97
|
-
Use footer for metadata:
|
|
98
|
-
|
|
99
|
-
**Breaking changes:**
|
|
100
|
-
```
|
|
101
|
-
feat(api)!: change authentication endpoint
|
|
102
|
-
|
|
103
|
-
BREAKING CHANGE: /api/login now requires email instead of username
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**Issue references:**
|
|
107
|
-
```
|
|
108
|
-
fix(cart): calculate tax correctly
|
|
109
|
-
|
|
110
|
-
Fixes #123
|
|
111
|
-
Closes #124
|
|
112
|
-
Related to #125
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
**Attribution:**
|
|
116
|
-
```
|
|
117
|
-
feat(dashboard): add analytics widget
|
|
118
|
-
|
|
119
|
-
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Attribution Footer
|
|
125
|
-
|
|
126
|
-
Add a simple attribution line in the footer when needed:
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
feat(feature): implement new capability
|
|
130
|
-
|
|
131
|
-
[Body explaining the change]
|
|
132
|
-
|
|
133
|
-
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Examples
|
|
139
|
-
|
|
140
|
-
### Simple Feature
|
|
141
|
-
```
|
|
142
|
-
feat(player): add jump mechanic
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Bug Fix with Context
|
|
146
|
-
```
|
|
147
|
-
fix(inventory): prevent item duplication
|
|
148
|
-
|
|
149
|
-
Items were duplicating when rapidly clicking the pickup button.
|
|
150
|
-
Added debounce logic to prevent double-processing.
|
|
151
|
-
|
|
152
|
-
Fixes #156
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Refactor with Explanation
|
|
156
|
-
```
|
|
157
|
-
refactor(rendering): extract camera controller
|
|
158
|
-
|
|
159
|
-
Moved camera logic from PlayerController to dedicated CameraController
|
|
160
|
-
for better separation of concerns and reusability.
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Performance Improvement
|
|
164
|
-
```
|
|
165
|
-
perf(physics): optimize collision detection
|
|
166
|
-
|
|
167
|
-
Changed from O(n²) all-pairs check to spatial hashing.
|
|
168
|
-
Reduces frame time by ~15ms with 100+ objects.
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Attribution Example
|
|
172
|
-
```
|
|
173
|
-
feat(multiplayer): add lobby system
|
|
174
|
-
|
|
175
|
-
Implements matchmaking lobby with room creation, joining, and ready-up.
|
|
176
|
-
Uses WebSocket for real-time updates.
|
|
177
|
-
|
|
178
|
-
Closes #89
|
|
179
|
-
|
|
180
|
-
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Usage in Skills
|
|
186
|
-
|
|
187
|
-
**Reference this file when:**
|
|
188
|
-
- Creating commits (Git or Plastic)
|
|
189
|
-
- Generating commit messages
|
|
190
|
-
- Validating commit format
|
|
191
|
-
- Writing PR/code review descriptions
|
|
192
|
-
|
|
193
|
-
**Load this file:**
|
|
194
|
-
```markdown
|
|
195
|
-
Load conventional commit format from ../../_shared/references/conventional-commits.md
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Then format all commits according to this standard.
|
|
1
|
+
# Conventional Commits
|
|
2
|
+
|
|
3
|
+
This reference file documents the conventional commit format used across the project.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Format
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
<type>(<scope>): <subject>
|
|
11
|
+
|
|
12
|
+
[optional body]
|
|
13
|
+
|
|
14
|
+
[optional footer]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Types
|
|
20
|
+
|
|
21
|
+
| Type | Description | Example |
|
|
22
|
+
|------|-------------|---------|
|
|
23
|
+
| **feat** | New feature | `feat(auth): add OAuth login` |
|
|
24
|
+
| **fix** | Bug fix | `fix(cart): calculate tax correctly` |
|
|
25
|
+
| **refactor** | Code restructuring (no behavior change) | `refactor(api): extract service layer` |
|
|
26
|
+
| **perf** | Performance improvement | `perf(query): optimize user lookup` |
|
|
27
|
+
| **test** | Adding or updating tests | `test(auth): add login edge cases` |
|
|
28
|
+
| **docs** | Documentation changes | `docs(readme): update installation steps` |
|
|
29
|
+
| **style** | Code style changes (formatting, etc.) | `style(lint): fix indentation` |
|
|
30
|
+
| **chore** | Build process or auxiliary tool changes | `chore(deps): update to Rails 7.1` |
|
|
31
|
+
| **ci** | CI/CD configuration changes | `ci(github): add test workflow` |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Scope
|
|
36
|
+
|
|
37
|
+
The scope is optional but recommended. It specifies which part of the codebase was affected:
|
|
38
|
+
|
|
39
|
+
**Examples:**
|
|
40
|
+
- `feat(player): add dash mechanic`
|
|
41
|
+
- `fix(inventory): prevent negative quantities`
|
|
42
|
+
- `refactor(ui): simplify menu navigation`
|
|
43
|
+
- `perf(rendering): batch sprite draws`
|
|
44
|
+
|
|
45
|
+
**Guidelines:**
|
|
46
|
+
- Use lowercase
|
|
47
|
+
- Be specific but concise
|
|
48
|
+
- Match your module/component names
|
|
49
|
+
- Omit if change is global
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Subject
|
|
54
|
+
|
|
55
|
+
The subject contains a succinct description of the change:
|
|
56
|
+
|
|
57
|
+
- **Use imperative mood:** "add" not "added" or "adds"
|
|
58
|
+
- **Don't capitalize first letter:** "add feature" not "Add feature"
|
|
59
|
+
- **No period at the end:** "fix bug" not "fix bug."
|
|
60
|
+
- **Limit to 50 characters**
|
|
61
|
+
|
|
62
|
+
**Good examples:**
|
|
63
|
+
- `feat(auth): add password reset flow`
|
|
64
|
+
- `fix(api): handle null responses`
|
|
65
|
+
- `refactor(utils): extract string helpers`
|
|
66
|
+
|
|
67
|
+
**Bad examples:**
|
|
68
|
+
- `feat(auth): Added password reset flow` (not imperative)
|
|
69
|
+
- `feat(auth): Add Password Reset Flow` (capitalized)
|
|
70
|
+
- `feat(auth): add password reset flow.` (period at end)
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Body (Optional)
|
|
75
|
+
|
|
76
|
+
Use the body to explain **what** and **why**, not **how**:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
feat(player): add dash mechanic
|
|
80
|
+
|
|
81
|
+
Adds a dash ability to the player character for enhanced mobility.
|
|
82
|
+
Dash has 1-second cooldown and consumes 10 stamina.
|
|
83
|
+
|
|
84
|
+
Closes #42
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Guidelines:**
|
|
88
|
+
- Wrap at 72 characters
|
|
89
|
+
- Separate from subject with blank line
|
|
90
|
+
- Focus on context and reasoning
|
|
91
|
+
- Link to issues if applicable
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Footer (Optional)
|
|
96
|
+
|
|
97
|
+
Use footer for metadata:
|
|
98
|
+
|
|
99
|
+
**Breaking changes:**
|
|
100
|
+
```
|
|
101
|
+
feat(api)!: change authentication endpoint
|
|
102
|
+
|
|
103
|
+
BREAKING CHANGE: /api/login now requires email instead of username
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Issue references:**
|
|
107
|
+
```
|
|
108
|
+
fix(cart): calculate tax correctly
|
|
109
|
+
|
|
110
|
+
Fixes #123
|
|
111
|
+
Closes #124
|
|
112
|
+
Related to #125
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Attribution:**
|
|
116
|
+
```
|
|
117
|
+
feat(dashboard): add analytics widget
|
|
118
|
+
|
|
119
|
+
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Attribution Footer
|
|
125
|
+
|
|
126
|
+
Add a simple attribution line in the footer when needed:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
feat(feature): implement new capability
|
|
130
|
+
|
|
131
|
+
[Body explaining the change]
|
|
132
|
+
|
|
133
|
+
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Examples
|
|
139
|
+
|
|
140
|
+
### Simple Feature
|
|
141
|
+
```
|
|
142
|
+
feat(player): add jump mechanic
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Bug Fix with Context
|
|
146
|
+
```
|
|
147
|
+
fix(inventory): prevent item duplication
|
|
148
|
+
|
|
149
|
+
Items were duplicating when rapidly clicking the pickup button.
|
|
150
|
+
Added debounce logic to prevent double-processing.
|
|
151
|
+
|
|
152
|
+
Fixes #156
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Refactor with Explanation
|
|
156
|
+
```
|
|
157
|
+
refactor(rendering): extract camera controller
|
|
158
|
+
|
|
159
|
+
Moved camera logic from PlayerController to dedicated CameraController
|
|
160
|
+
for better separation of concerns and reusability.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Performance Improvement
|
|
164
|
+
```
|
|
165
|
+
perf(physics): optimize collision detection
|
|
166
|
+
|
|
167
|
+
Changed from O(n²) all-pairs check to spatial hashing.
|
|
168
|
+
Reduces frame time by ~15ms with 100+ objects.
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Attribution Example
|
|
172
|
+
```
|
|
173
|
+
feat(multiplayer): add lobby system
|
|
174
|
+
|
|
175
|
+
Implements matchmaking lobby with room creation, joining, and ready-up.
|
|
176
|
+
Uses WebSocket for real-time updates.
|
|
177
|
+
|
|
178
|
+
Closes #89
|
|
179
|
+
|
|
180
|
+
Co-Authored-By: <AI Assistant Name (e.g., Codex, Claude, Pi Coding Agent)>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Usage in Skills
|
|
186
|
+
|
|
187
|
+
**Reference this file when:**
|
|
188
|
+
- Creating commits (Git or Plastic)
|
|
189
|
+
- Generating commit messages
|
|
190
|
+
- Validating commit format
|
|
191
|
+
- Writing PR/code review descriptions
|
|
192
|
+
|
|
193
|
+
**Load this file:**
|
|
194
|
+
```markdown
|
|
195
|
+
Load conventional commit format from ../../_shared/references/conventional-commits.md
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Then format all commits according to this standard.
|