create-pmos 0.166.0 → 0.167.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/package.json +1 -1
- package/payload/KIT-VERSION +1 -1
- package/payload/planning/evals/eval-calibration.md +1 -1
- package/payload/planning/okrs/health-budgets.md +1 -1
- package/payload/state/discoveries.md +1 -1
- package/workspace/guide/validate-with-typesafe.md +1 -1
- package/workspace/lib/typesafe-settings.js +15 -1
- package/workspace/package-lock.json +2 -2
- package/workspace/package.json +1 -1
- package/workspace/public/pm/c3-settings.js +12 -2
- package/workspace/server.js +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-pmos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.0",
|
|
4
4
|
"description": "Scaffold the PMOS portable kit — run the PMOS product-management workflow (initiative → lane-fit spec → contract → build → three gates, with work-type lanes for features, research, maintenance, incidents, and content) entirely inside your own repo, with all state as git-versioned files. Includes `workflow-sweep`, which audits the state every board derives from and separates real defects from work you simply have not done. `create-pmos workspace` also installs + launches the local Terminal Workspace GUI. No database, no network, no telemetry.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
package/payload/KIT-VERSION
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Eval calibration log"
|
|
4
4
|
description: "Append-only record of every PM override of an evaluator verdict."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-10-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-12T14:00:51Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Health budgets"
|
|
4
4
|
description: "Closed registry of health-budget anchors (D59), edited only by the PM."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-10-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-12T14:00:51Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: Reference
|
|
3
3
|
title: "Discoveries and friction log"
|
|
4
4
|
description: "Append-only record of what runs discovered and where the process rubbed."
|
|
5
|
-
generated: {by: process:create-pmos, at: "2026-10-
|
|
5
|
+
generated: {by: process:create-pmos, at: "2026-10-12T14:00:51Z"}
|
|
6
6
|
status: stable
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -112,7 +112,7 @@ The workspace reads the TypeSafe key only on this machine. After you save the ke
|
|
|
112
112
|
If you have no TypeSafe key, a model on your computer can answer the same questions. Two models are supported. Both use the same interface as Jev.
|
|
113
113
|
|
|
114
114
|
- **Winnow**: in a `winnow-inference` folder, run `python3 scripts/serve.py`. It uses port 8091. Winnow-12B needs about 16 GB of memory.
|
|
115
|
-
- **Laya**:
|
|
115
|
+
- **Laya**: in Settings, press **Set up Laya**. A terminal named Set up Laya opens with the commands typed in. Read them and press Enter. The first time, they install Laya into the PMOS data folder. Then Laya starts and uses port 8000. Laya is small and runs on a laptop. Laya stops when you close that terminal or restart the computer. Press **Set up Laya** again to start it.
|
|
116
116
|
|
|
117
117
|
1. Start the model.
|
|
118
118
|
2. Open Settings, then **Privacy and data**. Under **Local model if Jev is missing**, press **Winnow** or **Laya**.
|
|
@@ -90,6 +90,20 @@ function status(stateDir, env = null) {
|
|
|
90
90
|
return { present: false, source: null, local: null };
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/** The commands that install Laya into its own folder under the runtime directory (once) and start it on loopback.
|
|
94
|
+
* The workspace types them into a terminal and never runs them itself: the PM reads them and presses Enter (as D91's
|
|
95
|
+
* Whisper setup does). A folder of its own avoids the system Python, which newer Macs refuse to install into. */
|
|
96
|
+
function layaSetupCommand(stateDir, platform = process.platform) {
|
|
97
|
+
const dir = path.join(stateDir, 'laya');
|
|
98
|
+
const port = typesafe.BACKENDS.laya.port;
|
|
99
|
+
if (platform === 'win32') {
|
|
100
|
+
return `if (-not (Test-Path "${dir}\\Scripts\\laya-serve.exe")) { python -m venv "${dir}"; & "${dir}\\Scripts\\python" -m pip install "laya[serve]" }; `
|
|
101
|
+
+ `$env:LAYA_HOST="127.0.0.1"; $env:LAYA_PORT="${port}"; $env:LAYA_DEVICE="cpu"; $env:LAYA_PRELOAD="1"; & "${dir}\\Scripts\\laya-serve"`;
|
|
102
|
+
}
|
|
103
|
+
return `[ -x "${dir}/bin/laya-serve" ] || { python3 -m venv "${dir}" && "${dir}/bin/python" -m pip install "laya[serve]"; } && `
|
|
104
|
+
+ `LAYA_HOST=127.0.0.1 LAYA_PORT=${port} LAYA_DEVICE=cpu LAYA_PRELOAD=1 "${dir}/bin/laya-serve"`;
|
|
105
|
+
}
|
|
106
|
+
|
|
93
107
|
/** Save or clear the local fallback server. `backend` is 'winnow' or 'laya'; `port` defaults to that server's own. */
|
|
94
108
|
function setLocal(stateDir, { backend, port } = {}) {
|
|
95
109
|
const cur = read(stateDir);
|
|
@@ -163,4 +177,4 @@ function isExcluded(exclude, rel) {
|
|
|
163
177
|
});
|
|
164
178
|
}
|
|
165
179
|
|
|
166
|
-
module.exports = { adoptEnv, status, getKey, setKey, clearKey, setLocal, getRepo, setRepo, isExcluded, ENV_NAME, FILE };
|
|
180
|
+
module.exports = { adoptEnv, status, getKey, setKey, clearKey, setLocal, layaSetupCommand, getRepo, setRepo, isExcluded, ENV_NAME, FILE };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmos-workspace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pmos-workspace",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.167.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@xterm/addon-fit": "^0.11.0",
|
package/workspace/package.json
CHANGED
|
@@ -618,14 +618,24 @@ export function mountSettings(host, ctx = {}) {
|
|
|
618
618
|
M.localTest = r && r.ok ? { ok: true, text: 'Answered (' + (r.model || r.local) + ').' } : { ok: false, text: (r && r.error) || 'No answer.' };
|
|
619
619
|
draw();
|
|
620
620
|
};
|
|
621
|
+
const setup = async () => {
|
|
622
|
+
M.localTest = { busy: true }; draw();
|
|
623
|
+
const r = await pmPost('/api/typesafe/local/setup', {});
|
|
624
|
+
if (r && r.ok) {
|
|
625
|
+
M.typesafe = r.key; delete M.err['typesafe.local'];
|
|
626
|
+
M.localTest = { ok: !!r.started, text: r.started ? 'A terminal named Set up Laya opened with the commands typed in. Press Enter there, wait until Laya says it is running, then press Test.' : 'No terminal opened (' + (r.reason || 'unknown') + '). Run this in a terminal: ' + r.command };
|
|
627
|
+
} else { M.localTest = null; M.err['typesafe.local'] = (r && r.error) || 'Not started.'; }
|
|
628
|
+
draw();
|
|
629
|
+
};
|
|
621
630
|
const lt = M.localTest;
|
|
622
631
|
const note = !loc ? 'Off. With no TypeSafe key, Jev features stay off.'
|
|
623
632
|
: (t.source === 'local' ? 'No TypeSafe key, so ' + loc.name + ' answers every Jev question.' : 'TypeSafe answers first; ' + loc.name + ' answers when it fails.')
|
|
624
633
|
+ ' PMOS calls 127.0.0.1:' + loc.port + ' only. Nothing leaves this computer.' + (lt && !lt.busy ? ' ' + lt.text : '');
|
|
625
|
-
return frame({ key: 'typesafe.local', label: 'Local model if Jev is missing', help: '
|
|
634
|
+
return frame({ key: 'typesafe.local', label: 'Local model if Jev is missing', help: 'Press Set up Laya to install and start Laya in a terminal, or start Winnow (winnow-inference, port 8091) yourself and pick it here.', scope: 'computer',
|
|
626
635
|
err: M.err['typesafe.local'], note,
|
|
627
636
|
control: t ? el('div', { class: 'iacts' }, seg('Local model', [['off', 'Off'], ['winnow', 'Winnow'], ['laya', 'Laya']], cur, pick),
|
|
628
|
-
|
|
637
|
+
btn('Set up Laya', { variant: 'ghost', disabled: !!(lt && lt.busy), onclick: setup, attrs: { 'data-c3set-laya-setup': '' } }),
|
|
638
|
+
loc ? btn(lt && lt.busy ? 'Working' : 'Test', { variant: 'ghost', disabled: !!(lt && lt.busy), onclick: test }) : null) : tag('Reading') });
|
|
629
639
|
}
|
|
630
640
|
|
|
631
641
|
function appearanceSec() {
|
package/workspace/server.js
CHANGED
|
@@ -7976,6 +7976,17 @@ async function handleRequest(req, res) {
|
|
|
7976
7976
|
if (!out.ok) return json(res, { ok: false, error: out.error }, /choose|port/.test(out.error) ? 400 : 500);
|
|
7977
7977
|
return json(res, { ok: true, key: tsSettings.status(STATE) });
|
|
7978
7978
|
}
|
|
7979
|
+
/* Set up Laya: picks Laya as the local model and opens a terminal with the install-and-start commands typed in, not run.
|
|
7980
|
+
* The PM reads them and presses Enter; Laya then runs in that terminal on 127.0.0.1:8000 (D95). */
|
|
7981
|
+
if (p === '/api/typesafe/local/setup' && req.method === 'POST') {
|
|
7982
|
+
const saved = tsSettings.setLocal(STATE, { backend: 'laya' });
|
|
7983
|
+
if (!saved.ok) return json(res, { ok: false, error: saved.error }, 500);
|
|
7984
|
+
const command = tsSettings.layaSetupCommand(STATE);
|
|
7985
|
+
const home = homeWorkspace();
|
|
7986
|
+
const s = spawnSession({ name: 'Set up Laya', agent: 'shell', ws: home ? home.id : undefined, origin: 'laya-setup', initialInput: command });
|
|
7987
|
+
const started = !!s && s.state !== 'exited';
|
|
7988
|
+
return json(res, { ok: true, started, session: s ? s.id : null, command, key: tsSettings.status(STATE), reason: started ? '' : ((s && s.note) || 'could not start a terminal') });
|
|
7989
|
+
}
|
|
7979
7990
|
if (p === '/api/typesafe/local/test' && req.method === 'POST') {
|
|
7980
7991
|
if (!tsSettings.status(STATE).local) return json(res, { ok: false, error: 'No local model is set.' }, 409);
|
|
7981
7992
|
const r = await tsClient.ask({ key: tsClient.LOCAL_KEY, state: 'PMOS is checking that the local model answers.', retries: 0,
|